## Also execute instructions in src/squirrel/CMakeLists.txt
-ADD_SUBDIRECTORY(src/squirrel)
+ADD_SUBDIRECTORY(external/squirrel)
## Add squirrel lib dir to search path
-LINK_DIRECTORIES(src/squirrel)
+LINK_DIRECTORIES(external/squirrel)
## Some additional include paths
include_directories (${SUPERTUX_SOURCE_DIR}/src/)
-include_directories (${SUPERTUX_SOURCE_DIR}/src/squirrel/include/)
+include_directories (${SUPERTUX_SOURCE_DIR}/external/squirrel/include/)
+include_directories (${SUPERTUX_SOURCE_DIR}/external/)
+include_directories (${SUPERTUX_SOURCE_DIR}/external/obstack/)
## Build list of sources for supertux binary
-FILE(GLOB SUPERTUX_SOURCES RELATIVE ${SUPERTUX_SOURCE_DIR} src/*.cpp src/*/*.cpp src/obstack/*.c)
+FILE(GLOB SUPERTUX_SOURCES RELATIVE ${SUPERTUX_SOURCE_DIR} src/*.cpp src/*/*.cpp src/video/sdl/*.cpp external/obstack/*.c external/tinygettext/*.cpp)
+
+IF(HAVE_OPENGL)
+ FILE(GLOB SUPERTUX_OPENGL_SOURCES RELATIVE ${SUPERTUX_SOURCE_DIR} src/video/gl/*.cpp)
+ SET(SUPERTUX_SOURCES ${SUPERTUX_SOURCES} ${SUPERTUX_OPENGL_SOURCES})
+ENDIF(HAVE_OPENGL)
## Precompile "a few" headers in GCC
OPTION(PRECOMPILE_HEADERS "Precompile headers (experimental)" OFF)
OPTION(ENABLE_SQDBG "Build squirrel script interpreter with debugging options" OFF)
IF(ENABLE_SQDBG)
- include_directories (${SUPERTUX_SOURCE_DIR}/src/squirrel/)
- FILE(GLOB SQDBG_SOURCES RELATIVE ${SUPERTUX_SOURCE_DIR} src/squirrel/sqdbg/*.cpp)
+ include_directories (${SUPERTUX_SOURCE_DIR}/external/squirrel/)
+ FILE(GLOB SQDBG_SOURCES RELATIVE ${SUPERTUX_SOURCE_DIR} external/squirrel/sqdbg/*.cpp)
SET(SUPERTUX_SOURCES ${SQDBG_SOURCES} ${SUPERTUX_SOURCES})
ENDIF(ENABLE_SQDBG)
ADD_CUSTOM_COMMAND(
OUTPUT ${SUPERTUX_SOURCE_DIR}/src/scripting/wrapper.cpp ${SUPERTUX_SOURCE_DIR}/src/scripting/wrapper.hpp
COMMAND cd ${SUPERTUX_SOURCE_DIR} && ${CMAKE_CXX_COMPILER}
- ARGS -x "c++" -E -CC -DSCRIPTING_API src/scripting/wrapper.interface.hpp -o ${SUPERTUX_BINARY_DIR}/miniswig.tmp
+ ARGS -x "c++" -E -CC -DSCRIPTING_API src/scripting/wrapper.interface.hpp -o ${SUPERTUX_BINARY_DIR}/miniswig.tmp -I${SUPERTUX_SOURCE_DIR}/src
COMMAND tools/miniswig/miniswig
ARGS --input miniswig.tmp --output-cpp ${SUPERTUX_SOURCE_DIR}/src/scripting/wrapper.cpp --output-hpp ${SUPERTUX_SOURCE_DIR}/src/scripting/wrapper.hpp --module supertux --select-namespace Scripting
DEPENDS tools/miniswig/miniswig
## Add binreloc.c if enabled
IF(ENABLE_BINRELOC)
- SET(SUPERTUX_SOURCES ${SUPERTUX_SOURCES} ${SUPERTUX_SOURCE_DIR}/src/binreloc/binreloc.c)
+ SET(SUPERTUX_SOURCES ${SUPERTUX_SOURCES} ${SUPERTUX_SOURCE_DIR}/external/binreloc/binreloc.c)
ENDIF(ENABLE_BINRELOC)
TARGET_LINK_LIBRARIES(supertux2 ${CURL_LIBRARY})
ENDIF(HAVE_LIBCURL)
+# Warnings to add
+OPTION(WARNINGS "Enable long list of warnings for compiler to check" ON)
+IF(WARNINGS)
+ SET_PROPERTY(TARGET supertux2 APPEND PROPERTY COMPILE_FLAGS
+# -ansi fails in MinGW
+# still left: -Weffc++ -Wold-style-cast -Wpadded -Wconversion -Wundef -Wsign-conversion -Wshadow -Winline -Wunsafe-loop-optimizations -Wfloat-equal -Wswitch-default -Wswitch-enum -Wcast-qual -Wsign-promo -Woverloaded-virtual -Wmissing-format-attribute -Wstrict-overflow=5 -Wformat=2
+ "-fdiagnostics-show-option -O3 -pedantic -Wno-long-long -Wabi -Wctor-dtor-privacy -Wstrict-null-sentinel -Wcast-align -Wdisabled-optimization -Winit-self -Winvalid-pch -Wlogical-op -Wmissing-include-dirs -Wmissing-noreturn -Wpacked -Wredundant-decls -Wstack-protector")
+ENDIF(WARNINGS)
+
## Install stuff
IF(WIN32 AND NOT UNIX)
INSTALL(FILES ${SUPERTUX_SOURCE_DIR}/data/credits.txt DESTINATION ${INSTALL_SUBDIR_SHARE})
-FILE(GLOB INSTALL_DATA_DIRS ${SUPERTUX_SOURCE_DIR}/data/*/)
-message(STATUS blah ${INSTALL_DATA_DIRS} blah)
-
INSTALL(DIRECTORY data/images
data/fonts
data/levels
+
GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
+ Version 3, 29 June 2007
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
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
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. 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.
+them 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.
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
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.
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. 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.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
-\f
- 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.)
-\f
-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.
-\f
- 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
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey 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;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
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
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If 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.
-\f
- 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
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU 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.
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ 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.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+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.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
-\f
+
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
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
+state 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) 19yy <name of author>
+ Copyright (C) <year> <name of author>
- This program is free software; you can redistribute it and/or modify
+ 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
+ the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
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:
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
- Gnomovision version 69, Copyright (C) 19yy name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ <program> Copyright (C) <year> <name of author>
+ This program 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:
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
- <signature of Ty Coon>, 1 April 1989
- Ty Coon, President of Vice
+ The GNU 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 Lesser General
+Public License instead of this License. But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
-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.
-# Doxyfile 1.4.6
+# Doxyfile 1.6.1
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the
+# iconv built into libc) for the transcoding. See
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
+
PROJECT_NAME = SuperTux
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
PROJECT_NUMBER = SVN
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
OUTPUT_DIRECTORY = docs/doxygen
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of
+# source files, where putting all generated files in the same directory would
+# otherwise cause performance problems for the file system.
+
CREATE_SUBDIRS = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
+# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
+# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
+# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,
+# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak,
+# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
+
OUTPUT_LANGUAGE = English
-USE_WINDOWS_ENCODING = NO
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
+# "represents" "a" "an" "the"
+
ABBREVIATE_BRIEF = "The $name class" \
"The $name widget" \
"The $name file" \
a \
an \
the
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+
INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
FULL_PATH_NAMES = YES
-STRIP_FROM_PATH =
-STRIP_FROM_INC_PATH =
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip.
+
+STRIP_FROM_PATH =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful is your file systems
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like regular Qt-style comments
+# (thus requiring an explicit @brief command for a brief description.)
+
JAVADOC_AUTOBRIEF = YES
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
+# interpret the first line (until the first dot) of a Qt-style
+# comment as the brief description. If set to NO, the comments
+# will behave just like regular Qt-style comments (thus requiring
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
MULTILINE_CPP_IS_BRIEF = NO
-DETAILS_AT_TOP = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
+# be part of the file/class/namespace that contains it.
+
SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
TAB_SIZE = 8
-ALIASES =
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
OPTIMIZE_OUTPUT_FOR_C = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
+# sources only. Doxygen will then generate output that is more tailored for
+# Java. For instance, namespaces will be presented as packages, qualified
+# scopes will look different, etc.
+
OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources only. Doxygen will then generate output that is more tailored for
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it parses.
+# With this tag you can assign which parser to use for a given extension.
+# Doxygen has a built-in mapping, but you can override or extend it using this tag.
+# The format is ext=language, where ext is a file extension, and language is one of
+# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP,
+# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat
+# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran),
+# use: inc=Fortran f=C. Note that for custom extensions you also need to set FILE_PATTERNS otherwise the files are not read by doxygen.
+
+EXTENSION_MAPPING =
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should
+# set this tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
+# func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+
BUILTIN_STL_SUPPORT = YES
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
+# Doxygen will parse them like normal C++ but will assume all classes use public
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate getter
+# and setter methods for a property. Setting this option to YES (the default)
+# will make doxygen to replace the get and set methods by a property in the
+# documentation. This will only work if the methods are indeed getting or
+# setting a simple type. If this is not the case, or you want to show the
+# methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
DISTRIBUTE_GROUP_DOC = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
SUBGROUPING = YES
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
+# is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically
+# be useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT = NO
+
+# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to
+# determine which symbols to keep in memory and which to flush to disk.
+# When the cache is full, less often used symbols will be written to disk.
+# For small to medium size projects (<1000 input files) the default value is
+# probably good enough. For larger projects a too small cache size can cause
+# doxygen to be busy swapping symbols to and from disk most of the time
+# causing a significant performance penality.
+# If the system has enough physical memory increasing the cache will improve the
+# performance by keeping more symbols in memory. Note that the value works on
+# a logarithmic scale so increasing the size by one will rougly double the
+# memory usage. The cache size is given by this formula:
+# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
+# corresponding to a cache size of 2^16 = 65536 symbols
+
+SYMBOL_CACHE_SIZE = 0
+
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
EXTRACT_ALL = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
EXTRACT_PRIVATE = YES
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
EXTRACT_STATIC = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
EXTRACT_LOCAL_CLASSES = YES
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+
EXTRACT_LOCAL_METHODS = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base
+# name of the file that contains the anonymous namespace. By default
+# anonymous namespace are hidden.
+
+EXTRACT_ANON_NSPACES = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+
CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
HIDE_SCOPE_NAMES = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
SHOW_INCLUDE_FILES = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
SORT_BRIEF_DOCS = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the (brief and detailed) documentation of class members so that constructors and destructors are listed first. If set to NO (the default) the constructors will appear in the respective orders defined by SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
+# hierarchy of group names into alphabetical order. If set to NO (the default)
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
SORT_BY_SCOPE_NAME = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
GENERATE_DEPRECATEDLIST= YES
-ENABLED_SECTIONS =
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or define consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and defines in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
SHOW_USED_FILES = YES
+
+# If the sources in your project are distributed over multiple directories
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
+# in the documentation. The default is NO.
+
SHOW_DIRECTORIES = NO
-FILE_VERSION_FILTER =
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
+# This will remove the Files entry from the Quick Index and from the
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
+# Namespaces page.
+# This will remove the Namespaces entry from the Quick Index
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
+# provided by doxygen. Whatever the program writes to standard output
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by
+# doxygen. The layout file controls the global structure of the generated output files
+# in an output format independent way. The create the layout file that represents
+# doxygen's defaults, run doxygen with the -l option. You can optionally specify a
+# file name after the option, if omitted DoxygenLayout.xml will be used as the name
+# of the layout file.
+
+LAYOUT_FILE =
+
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
QUIET = YES
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
WARN_IF_UNDOCUMENTED = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
WARN_IF_DOC_ERROR = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for
+# functions that are documented, but have no documentation for their parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
+# documentation.
+
WARN_NO_PARAMDOC = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
+# be obtained via FILE_VERSION_FILTER)
+
WARN_FORMAT = "$file:$line: $text"
-WARN_LOGFILE =
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE =
+
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
INPUT = src/
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
+# also the default input encoding. Doxygen uses libiconv (or the iconv built
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
+# the list of possible encodings.
+
+INPUT_ENCODING = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
+
FILE_PATTERNS = *.cpp \
- *.hpp
+ *.hpp \
+ */*.hpp \
+ */*.cpp
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
RECURSIVE = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
EXCLUDE = src/squirrel/
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
+# directories that are symbolic links (a Unix filesystem feature) are excluded
+# from the input.
+
EXCLUDE_SYMLINKS = NO
-EXCLUDE_PATTERNS =
-EXAMPLE_PATH =
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS =
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
EXAMPLE_PATTERNS = *
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
EXAMPLE_RECURSIVE = NO
-IMAGE_PATH =
-INPUT_FILTER =
-FILTER_PATTERNS =
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output.
+# If FILTER_PATTERNS is specified, this tag will be
+# ignored.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis.
+# Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match.
+# The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
+# is applied to all files.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
FILTER_SOURCE_FILES = NO
+
#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+
SOURCE_BROWSER = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
INLINE_SOURCES = YES
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES
+# then for each documented function all documented
+# functions referencing it will be listed.
+
REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
REFERENCES_RELATION = YES
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code.
+# Otherwise they will link to the documentation.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
+# will need version 4.8.6 or higher.
+
USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
VERBATIM_HEADERS = YES
+
#---------------------------------------------------------------------------
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
ALPHABETICAL_INDEX = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
COLS_IN_ALPHA_INDEX = 5
-IGNORE_PREFIX =
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
HTML_FILE_EXTENSION = .html
-HTML_HEADER =
-HTML_FOOTER =
-HTML_STYLESHEET =
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet. Note that doxygen will try to copy
+# the style sheet file to the HTML output directory, so don't put your own
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET =
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+
HTML_ALIGN_MEMBERS = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded. For this to work a browser that supports
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+
+HTML_DYNAMIC_SECTIONS = NO
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files
+# will be generated that can be used as input for Apple's Xcode 3
+# integrated development environment, introduced with OSX 10.5 (Leopard).
+# To create a documentation set, doxygen will generate a Makefile in the
+# HTML output directory. Running make will produce the docset in that
+# directory and running "make install" will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
+# it at startup.
+# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information.
+
+GENERATE_DOCSET = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
+# feed. A documentation feed provides an umbrella under which multiple
+# documentation sets from a single provider (such as a company or product suite)
+# can be grouped.
+
+DOCSET_FEEDNAME = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
+# should uniquely identify the documentation set bundle. This should be a
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID = org.doxygen.Project
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
+# of the generated HTML documentation.
+
GENERATE_HTMLHELP = NO
-CHM_FILE =
-HHC_LOCATION =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file
+# content.
+
+CHM_INDEX_ENCODING =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
TOC_EXPAND = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER
+# are set, an additional index file will be generated that can be used as input for
+# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated
+# HTML documentation.
+
+GENERATE_QHP = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can
+# be used to specify the file name of the resulting .qch file.
+# The path specified is relative to the HTML output folder.
+
+QCH_FILE =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#namespace
+
+QHP_NAMESPACE =
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#virtual-folders
+
+QHP_VIRTUAL_FOLDER = doc
+
+# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add.
+# For more information please see
+# http://doc.trolltech.com/qthelpproject.html#custom-filters
+
+QHP_CUST_FILTER_NAME =
+
+# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see
+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">Qt Help Project / Custom Filters</a>.
+
+QHP_CUST_FILTER_ATTRS =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's
+# filter section matches.
+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">Qt Help Project / Filter Attributes</a>.
+
+QHP_SECT_FILTER_ATTRS =
+
+# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can
+# be used to specify the location of Qt's qhelpgenerator.
+# If non-empty doxygen will try to run qhelpgenerator on the generated
+# .qhp file.
+
+QHG_LOCATION =
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it.
+
DISABLE_INDEX = NO
+
+# This tag can be used to set the number of enum values (range [1..20])
+# that doxygen will group on one line in the generated HTML documentation.
+
ENUM_VALUES_PER_LINE = 4
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information.
+# If the tag value is set to YES, a side panel will be generated
+# containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).
+# Windows users are probably better off using the HTML help feature.
+
GENERATE_TREEVIEW = YES
+
+# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories,
+# and Class Hierarchy pages using a tree view instead of an ordered list.
+
+USE_INLINE_TREES = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
TREEVIEW_WIDTH = 250
+
+# Use this tag to change the font size of Latex formulas included
+# as images in the HTML documentation. The default is 10. Note that
+# when you change the font size after a successful doxygen run you need
+# to manually remove any form_*.png images from the HTML output directory
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE = 10
+
+# When the SEARCHENGINE tag is enable doxygen will generate a search box for the HTML output. The underlying search engine uses javascript
+# and DHTML and should work on any modern browser. Note that when using HTML help (GENERATE_HTMLHELP) or Qt help (GENERATE_QHP)
+# there is already a search function so this one should typically
+# be disabled.
+
+SEARCHENGINE = NO
+
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+
LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, a4wide, letter, legal and
+# executive. If left blank a4wide will be used.
+
PAPER_TYPE = a4wide
-EXTRA_PACKAGES =
-LATEX_HEADER =
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
PDF_HYPERLINKS = NO
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
USE_PDFLATEX = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
LATEX_BATCHMODE = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
LATEX_HIDE_INDICES = NO
+
+# If LATEX_SOURCE_CODE is set to YES then doxygen will include source code with syntax highlighting in the LaTeX output. Note that which sources are shown also depends on other settings such as SOURCE_BROWSER.
+
+LATEX_SOURCE_CODE = NO
+
#---------------------------------------------------------------------------
# configuration options related to the RTF output
#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
RTF_HYPERLINKS = NO
-RTF_STYLESHEET_FILE =
-RTF_EXTENSIONS_FILE =
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE =
+
#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
MAN_LINKS = NO
+
#---------------------------------------------------------------------------
# configuration options related to the XML output
#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
XML_OUTPUT = xml
-XML_SCHEMA =
-XML_DTD =
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_SCHEMA =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_DTD =
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
XML_PROGRAMLISTING = YES
+
#---------------------------------------------------------------------------
# configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
GENERATE_AUTOGEN_DEF = NO
+
#---------------------------------------------------------------------------
# configuration options related to the Perl module output
#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader.
+# This is useful
+# if you want to understand what is going on.
+# On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
PERLMOD_PRETTY = YES
-PERLMOD_MAKEVAR_PREFIX =
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
#---------------------------------------------------------------------------
-# Configuration options related to the preprocessor
+# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
SEARCH_INCLUDES = YES
-INCLUDE_PATH =
-INCLUDE_FILE_PATTERNS =
-PREDEFINED =
-EXPAND_AS_DEFINED =
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+
+PREDEFINED =
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all function-like macros that are alone
+# on a line, have an all uppercase name, and do not end with a semicolon. Such
+# function macros are typically used for boiler-plate code, and will confuse
+# the parser if not removed.
+
SKIP_FUNCTION_MACROS = YES
+
#---------------------------------------------------------------------------
-# Configuration::additions related to external references
+# Configuration::additions related to external references
#---------------------------------------------------------------------------
-TAGFILES =
-GENERATE_TAGFILE =
+
+# The TAGFILES option can be used to specify one or more tagfiles.
+# Optionally an initial location of the external documentation
+# can be added for each tagfile. The format of a tag file without
+# this location is as follows:
+#
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+#
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths or
+# URLs. If a location is present for each tag, the installdox tool
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
EXTERNAL_GROUPS = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
PERL_PATH = /usr/bin/perl
+
#---------------------------------------------------------------------------
-# Configuration options related to the dot tool
+# Configuration options related to the dot tool
#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option is superseded by the HAVE_DOT option below. This is only a
+# fallback. It is recommended to install and use dot, since it yields more
+# powerful graphs.
+
CLASS_DIAGRAMS = NO
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH =
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
HIDE_UNDOC_RELATIONS = NO
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
HAVE_DOT = YES
+
+# By default doxygen will write a font called FreeSans.ttf to the output
+# directory and reference it in all dot files that doxygen generates. This
+# font does not include all possible unicode characters however, so when you need
+# these (or just want a differently looking font) you can specify the font name
+# using DOT_FONTNAME. You need need to make sure dot is able to find the font,
+# which can be done by putting it in a standard location or by setting the
+# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory
+# containing the font.
+
+DOT_FONTNAME = FreeSans
+
+# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
+# The default size is 10pt.
+
+DOT_FONTSIZE = 10
+
+# By default doxygen will tell dot to use the output directory to look for the
+# FreeSans.ttf font (which doxygen will put there itself). If you specify a
+# different font using DOT_FONTNAME you can set the path where dot
+# can find it using this tag.
+
+DOT_FONTPATH =
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# the CLASS_DIAGRAMS tag to NO.
+
CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for groups, showing the direct groups dependencies
+
GROUP_GRAPHS = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
UML_LOOK = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
TEMPLATE_RELATIONS = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then
+# doxygen will generate a call dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable call graphs
+# for selected functions only using the \callgraph command.
+
CALL_GRAPH = YES
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
+# doxygen will generate a caller dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable caller
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will graphical hierarchy of all classes instead of a textual one.
+
GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
DOT_IMAGE_FORMAT = png
-DOT_PATH =
-DOTFILE_DIRS =
-MAX_DOT_GRAPH_WIDTH = 1024
-MAX_DOT_GRAPH_HEIGHT = 1024
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
+# nodes that will be shown in the graph. If the number of nodes in a graph
+# becomes larger than this value, doxygen will truncate the graph, which is
+# visualized by representing a node as a red box. Note that doxygen if the
+# number of direct children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
MAX_DOT_GRAPH_DEPTH = 1000
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not
+# seem to support this out of the box. Warning: Depending on the platform used,
+# enabling this option may lead to badly anti-aliased labels on the edges of
+# a graph (i.e. they become hard to read).
+
DOT_TRANSPARENT = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# support this, this feature is disabled by default.
+
DOT_MULTI_TARGETS = YES
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
DOT_CLEANUP = YES
-#---------------------------------------------------------------------------
-# Configuration::additions related to the search engine
-#---------------------------------------------------------------------------
-SEARCHENGINE = NO
--- /dev/null
+# SuperTux
+# Copyright (C) 2009 Ingo Ruhnke <grumbel@gmx.de>
+#
+# 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 3 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, see <http:#www.gnu.org/licenses/>.
+
+class Project:
+ def __init__(self):
+ self.build_squirrel()
+ self.build_tinygettext()
+ self.build_binreloc()
+ self.build_supertux()
+ self.build_tests()
+
+ def build_tinygettext(self):
+ env = Environment(CPPPATH=["external/tinygettext/",
+ "external/squirrel/include/",
+ ".",
+ "src"])
+ env.ParseConfig("sdl-config --libs --cflags")
+ self.libtinygettext = env.StaticLibrary("tinygettext", Glob("external/tinygettext/*.cpp"))
+
+ def build_binreloc(self):
+ env = Environment(CPPPATH=["external/binreloc/", "."])
+ self.libbinreloc = env.StaticLibrary("binreloc", "external/binreloc/binreloc.c")
+
+ def build_squirrel(self):
+ env = Environment(CPPPATH=["external/squirrel/include/"])
+ self.libsquirrel = env.StaticLibrary("squirrel",
+ Glob("external/squirrel/squirrel/*.cpp") +
+ Glob("external/squirrel/sqstdlib/*.cpp") +
+ Glob("external/squirrel/sqstdlib/*.c"))
+
+ def build_supertux(self):
+ self.env = Environment(CPPPATH=["external/squirrel/include/",
+ "external/",
+ "external/obstack",
+ "src/",
+ "/usr/include/AL/", # yuck
+ "."],
+ CXXFLAGS=["-O2", "-g3",
+ "-ansi",
+ "-pedantic",
+ "-Wall",
+ "-Wextra",
+ "-Wnon-virtual-dtor",
+ # "-Weffc++",
+ # "-Wconversion",
+ "-Werror",
+ # "-Wshadow",
+ "-Wcast-qual",
+ "-Winit-self", # only works with >= -O1
+ "-Wno-unused-parameter"])
+
+ # Add libraries
+ self.env.ParseConfig("sdl-config --libs --cflags")
+ self.env.ParseConfig("pkg-config --libs --cflags openal")
+ self.env.ParseConfig("pkg-config --libs --cflags vorbis vorbisfile ogg")
+ self.env.Append(LIBS=[self.libsquirrel, self.libbinreloc, self.libtinygettext])
+ self.env.Append(LIBS=["SDL_image", "curl", "GL", "physfs"])
+
+ # Create config.h
+ self.iconv_const = 0
+ config_h = open('config.h', 'w')
+ config_h.write('#define PACKAGE_NAME "Supertux"\n')
+ config_h.write('#define PACKAGE_VERSION "Milestone 2"\n')
+ config_h.write('#define ENABLE_BINRELOC 1\n')
+ config_h.write('#define APPDATADIR "data"\n')
+ config_h.write('#define HAVE_LIBCURL 1\n')
+ config_h.write('#define HAVE_OPENGL 1\n')
+ config_h.write('#define DEBUG 1\n')
+ config_h.write('#define ICONV_CONST %s\n' % self.iconv_const)
+ config_h.close()
+
+ version_h = open('version.h', 'w')
+ version_h.close()
+
+ # base source
+ supertux_sources = Glob("src/*.cpp") + Glob("src/*/*.cpp")
+
+ # optional video drivers
+ supertux_sources += Glob("src/video/gl/*.cpp")
+ supertux_sources += Glob("src/video/sdl/*.cpp")
+
+ self.libsupertux = self.env.StaticLibrary("supertux", supertux_sources)
+ self.env.Program("supertux", ["src/main.cpp", self.libsupertux])
+
+ def build_tests(self):
+ for filename in Glob("test/*_test.cpp", strings=True):
+ self.env.Program(filename[:-4], [filename, self.libsupertux])
+
+project = Project()
+
+# EOF #
--- /dev/null
+# -*- mode: python -*-
+
+SConscript('SConscript', variant_dir='build', duplicate=0)
+
+# EOF #
- TODO
+Note: Controversial list of things currently broken and controversial
+solutions for them.
-The TODO is now located at http://supertux.lethargik.org/wiki/TODO
+Coding Standard
+===============
+
+* no external libraries in src/, they go to external/
+
+* proper separation between engine and game specific code (especially
+ sound and video handling)
+
+* normalize #include directives (all refer to top level dir)
+
+* use SCons instead of CMake
+
+* make code clean: "-O2", "-g3",
+ "-ansi",
+ "-pedantic",
+ "-Wall",
+ "-Wextra",
+ "-Wnon-virtual-dtor",
+ "-Weffc++",
+ "-Wconversion",
+ "-Werror",
+ "-Wshadow",
+ "-Wcast-qual",
+ "-Winit-self", # only works with >= -O1
+ "-Wno-unused-parameter",
+
+* do not use raw pointer, especially not for Sprite and Surface
+
+* properly separate data members and member functions, don't mix them
+ in the same section
+
+* write namespaces like: "namespace NameSpace {", no newline before the {
+
+* only do one variable initialization per line, not multiple as its
+ currently often done in initialization list
+
+* conditional includes should be indended (makes it easier to handle
+ in include optimization):
+
+#ifdef FOOBAR
+# include "foobar.hpp"
+#endif
+
+* remove overuse of multi-inheritance
+
+* remove overuse of friend'ship
+
+* maybe mark interfaces as interfaces (ISerializable or SerializableInterface)
+
+* split files with multiple classes into multiple files with one class each
+
+
+TODO
+====
+
+* GameObject::RemoveListenerListEntry: Ughs, somebody trying to
+ implement a list class within in the GameObject?!
+
+* replace random generator with mersene twister and/or move to external/
+
+* check the code with Valgrind
+
+* cleanup doxygen comments, use /** */, nothing else
+
+* static vs anonymous namespace
+
+* use Vector in Physics for 'a' and 'v'
+
+* add --datadir DIR (data/) and --userdir DIR (~/.supertux/)
+
+* make gravity a constant
+
+* funky side effect of too much global variables: when having a
+ savegame with large or firetux and then starting that game, Tux in
+ the menu background will grow and be visible that way for a fraction
+ of a second
+
+* write scripts for include sorting and include guard checking that
+ can be run automatically
+
+* md5.hpp and random_generator.hpp could go to external/
+
+* rename Vector -> Vector2f
+
+* get rid of global SDL_Screen* screen variable
+
+* identify all global variables and make them ugly (g_ or globals::)
+
+* get rid of SCREEN_WIDTH/SCREEN_HEIGHT
+
+* is version.h actually needed?
+
+* resolution menu entry moves the wrong way around
+
+* write scripts to automatically check for:
+
+ - all includes are relative to top level dir
+
+ - include guards are proper
+
+* move SVN to http://code.google.com (maybe one day)
+
+* move bugtracker to http://code.google.com (much simpler, less useless)
+
+
+# EOF #
--- /dev/null
+/*
+ * BinReloc - a library for creating relocatable executables
+ * Written by: Hongli Lai <h.lai@chello.nl>
+ * http://autopackage.org/
+ *
+ * This source code is public domain. You can relicense this code
+ * under whatever license you want.
+ *
+ * See http://autopackage.org/docs/binreloc/ for
+ * more information and how to use this.
+ */
+
+#ifndef __BINRELOC_C__
+#define __BINRELOC_C__
+
+// [Christoph] use config.h, which defines ENABLE_BINRELOC
+#include <config.h>
+
+#ifdef ENABLE_BINRELOC
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <unistd.h>
+#endif /* ENABLE_BINRELOC */
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <string.h>
+#include "binreloc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+
+/** @internal
+ * Find the canonical filename of the executable. Returns the filename
+ * (which must be freed) or NULL on error. If the parameter 'error' is
+ * not NULL, the error code will be stored there, if an error occurred.
+ */
+static char *
+_br_find_exe (BrInitError *error)
+{
+#ifndef ENABLE_BINRELOC
+ if (error)
+ *error = BR_INIT_ERROR_DISABLED;
+ return NULL;
+#else
+ char *path, *path2, *line, *result;
+ size_t buf_size;
+ ssize_t size;
+ struct stat stat_buf;
+ FILE *f;
+
+ /* Read from /proc/self/exe (symlink) */
+ if (sizeof (path) > SSIZE_MAX)
+ buf_size = SSIZE_MAX - 1;
+ else
+ buf_size = PATH_MAX - 1;
+ path = (char *) malloc (buf_size);
+ if (path == NULL) {
+ /* Cannot allocate memory. */
+ if (error)
+ *error = BR_INIT_ERROR_NOMEM;
+ return NULL;
+ }
+ path2 = (char *) malloc (buf_size);
+ if (path2 == NULL) {
+ /* Cannot allocate memory. */
+ if (error)
+ *error = BR_INIT_ERROR_NOMEM;
+ free (path);
+ return NULL;
+ }
+
+ strncpy (path2, "/proc/self/exe", buf_size - 1);
+
+ while (1) {
+ int i;
+
+ size = readlink (path2, path, buf_size - 1);
+ if (size == -1) {
+ /* Error. */
+ free (path2);
+ break;
+ }
+
+ /* readlink() success. */
+ path[size] = '\0';
+
+ /* Check whether the symlink's target is also a symlink.
+ * We want to get the final target. */
+ i = stat (path, &stat_buf);
+ if (i == -1) {
+ /* Error. */
+ free (path2);
+ break;
+ }
+
+ /* stat() success. */
+ if (!S_ISLNK (stat_buf.st_mode)) {
+ /* path is not a symlink. Done. */
+ free (path2);
+ return path;
+ }
+
+ /* path is a symlink. Continue loop and resolve this. */
+ strncpy (path, path2, buf_size - 1);
+ }
+
+
+ /* readlink() or stat() failed; this can happen when the program is
+ * running in Valgrind 2.2. Read from /proc/self/maps as fallback. */
+
+ buf_size = PATH_MAX + 128;
+ line = (char *) realloc (path, buf_size);
+ if (line == NULL) {
+ /* Cannot allocate memory. */
+ free (path);
+ if (error)
+ *error = BR_INIT_ERROR_NOMEM;
+ return NULL;
+ }
+
+ f = fopen ("/proc/self/maps", "r");
+ if (f == NULL) {
+ free (line);
+ if (error)
+ *error = BR_INIT_ERROR_OPEN_MAPS;
+ return NULL;
+ }
+
+ /* The first entry should be the executable name. */
+ result = fgets (line, (int) buf_size, f);
+ if (result == NULL) {
+ fclose (f);
+ free (line);
+ if (error)
+ *error = BR_INIT_ERROR_READ_MAPS;
+ return NULL;
+ }
+
+ /* Get rid of newline character. */
+ buf_size = strlen (line);
+ if (buf_size <= 0) {
+ /* Huh? An empty string? */
+ fclose (f);
+ free (line);
+ if (error)
+ *error = BR_INIT_ERROR_INVALID_MAPS;
+ return NULL;
+ }
+ if (line[buf_size - 1] == 10)
+ line[buf_size - 1] = 0;
+
+ /* Extract the filename; it is always an absolute path. */
+ path = strchr (line, '/');
+
+ /* Sanity check. */
+ if (strstr (line, " r-xp ") == NULL || path == NULL) {
+ fclose (f);
+ free (line);
+ if (error)
+ *error = BR_INIT_ERROR_INVALID_MAPS;
+ return NULL;
+ }
+
+ path = strdup (path);
+ free (line);
+ fclose (f);
+ return path;
+#endif /* ENABLE_BINRELOC */
+}
+
+
+/** @internal
+ * Find the canonical filename of the executable which owns symbol.
+ * Returns a filename which must be freed, or NULL on error.
+ */
+static char *
+_br_find_exe_for_symbol (const void *symbol, BrInitError *error)
+{
+ symbol = symbol; // [Christoph] mark it as used
+#ifndef ENABLE_BINRELOC
+ if (error)
+ *error = BR_INIT_ERROR_DISABLED;
+ return (char *) NULL;
+#else
+ #define SIZE PATH_MAX + 100
+ FILE *f;
+ size_t address_string_len;
+ char *address_string, line[SIZE], *found;
+
+ if (symbol == NULL)
+ return (char *) NULL;
+
+ f = fopen ("/proc/self/maps", "r");
+ if (f == NULL)
+ return (char *) NULL;
+
+ address_string_len = 4;
+ address_string = (char *) malloc (address_string_len);
+ found = (char *) NULL;
+
+ while (!feof (f)) {
+ char *start_addr, *end_addr, *end_addr_end, *file;
+ void *start_addr_p, *end_addr_p;
+ size_t len;
+
+ if (fgets (line, SIZE, f) == NULL)
+ break;
+
+ /* Sanity check. */
+ if (strstr (line, " r-xp ") == NULL || strchr (line, '/') == NULL)
+ continue;
+
+ /* Parse line. */
+ start_addr = line;
+ end_addr = strchr (line, '-');
+ file = strchr (line, '/');
+
+ /* More sanity check. */
+ if (!(file > end_addr && end_addr != NULL && end_addr[0] == '-'))
+ continue;
+
+ end_addr[0] = '\0';
+ end_addr++;
+ end_addr_end = strchr (end_addr, ' ');
+ if (end_addr_end == NULL)
+ continue;
+
+ end_addr_end[0] = '\0';
+ len = strlen (file);
+ if (len == 0)
+ continue;
+ if (file[len - 1] == '\n')
+ file[len - 1] = '\0';
+
+ /* Get rid of "(deleted)" from the filename. */
+ len = strlen (file);
+ if (len > 10 && strcmp (file + len - 10, " (deleted)") == 0)
+ file[len - 10] = '\0';
+
+ /* I don't know whether this can happen but better safe than sorry. */
+ len = strlen (start_addr);
+ if (len != strlen (end_addr))
+ continue;
+
+
+ /* Transform the addresses into a string in the form of 0xdeadbeef,
+ * then transform that into a pointer. */
+ if (address_string_len < len + 3) {
+ address_string_len = len + 3;
+ address_string = (char *) realloc (address_string, address_string_len);
+ }
+
+ memcpy (address_string, "0x", 2);
+ memcpy (address_string + 2, start_addr, len);
+ address_string[2 + len] = '\0';
+ sscanf (address_string, "%p", &start_addr_p);
+
+ memcpy (address_string, "0x", 2);
+ memcpy (address_string + 2, end_addr, len);
+ address_string[2 + len] = '\0';
+ sscanf (address_string, "%p", &end_addr_p);
+
+
+ if (symbol >= start_addr_p && symbol < end_addr_p) {
+ found = file;
+ break;
+ }
+ }
+
+ free (address_string);
+ fclose (f);
+
+ if (found == NULL)
+ return (char *) NULL;
+ else
+ return strdup (found);
+#endif /* ENABLE_BINRELOC */
+}
+
+
+#ifndef BINRELOC_RUNNING_DOXYGEN
+ #undef NULL
+ #define NULL ((void *) 0) /* typecasted as char* for C++ type safeness */
+#endif
+
+static char *exe = (char *) NULL;
+
+
+/** Initialize the BinReloc library (for applications).
+ *
+ * This function must be called before using any other BinReloc functions.
+ * It attempts to locate the application's canonical filename.
+ *
+ * @note If you want to use BinReloc for a library, then you should call
+ * br_init_lib() instead.
+ *
+ * @param error If BinReloc failed to initialize, then the error code will
+ * be stored in this variable. Set to NULL if you want to
+ * ignore this. See #BrInitError for a list of error codes.
+ *
+ * @returns 1 on success, 0 if BinReloc failed to initialize.
+ */
+int
+br_init (BrInitError *error)
+{
+ exe = _br_find_exe (error);
+ return exe != NULL;
+}
+
+
+/** Initialize the BinReloc library (for libraries).
+ *
+ * This function must be called before using any other BinReloc functions.
+ * It attempts to locate the calling library's canonical filename.
+ *
+ * @note The BinReloc source code MUST be included in your library, or this
+ * function won't work correctly.
+ *
+ * @param error If BinReloc failed to initialize, then the error code will
+ * be stored in this variable. Set to NULL if you want to
+ * ignore this. See #BrInitError for a list of error codes.
+ *
+ * @returns 1 on success, 0 if a filename cannot be found.
+ */
+int
+br_init_lib (BrInitError *error)
+{
+ exe = _br_find_exe_for_symbol ((const void *) "", error);
+ return exe != NULL;
+}
+
+
+/** Find the canonical filename of the current application.
+ *
+ * @param default_exe A default filename which will be used as fallback.
+ * @returns A string containing the application's canonical filename,
+ * which must be freed when no longer necessary. If BinReloc is
+ * not initialized, or if br_init() failed, then a copy of
+ * default_exe will be returned. If default_exe is NULL, then
+ * NULL will be returned.
+ */
+char *
+br_find_exe (const char *default_exe)
+{
+ if (exe == (char *) NULL) {
+ /* BinReloc is not initialized. */
+ if (default_exe != (const char *) NULL)
+ return strdup (default_exe);
+ else
+ return (char *) NULL;
+ }
+ return strdup (exe);
+}
+
+
+/** Locate the directory in which the current application is installed.
+ *
+ * The prefix is generated by the following pseudo-code evaluation:
+ * \code
+ * dirname(exename)
+ * \endcode
+ *
+ * @param default_dir A default directory which will used as fallback.
+ * @return A string containing the directory, which must be freed when no
+ * longer necessary. If BinReloc is not initialized, or if the
+ * initialization function failed, then a copy of default_dir
+ * will be returned. If default_dir is NULL, then NULL will be
+ * returned.
+ */
+char *
+br_find_exe_dir (const char *default_dir)
+{
+ if (exe == NULL) {
+ /* BinReloc not initialized. */
+ if (default_dir != NULL)
+ return strdup (default_dir);
+ else
+ return NULL;
+ }
+
+ return br_dirname (exe);
+}
+
+
+/** Locate the prefix in which the current application is installed.
+ *
+ * The prefix is generated by the following pseudo-code evaluation:
+ * \code
+ * dirname(dirname(exename))
+ * \endcode
+ *
+ * @param default_prefix A default prefix which will used as fallback.
+ * @return A string containing the prefix, which must be freed when no
+ * longer necessary. If BinReloc is not initialized, or if
+ * the initialization function failed, then a copy of default_prefix
+ * will be returned. If default_prefix is NULL, then NULL will be returned.
+ */
+char *
+br_find_prefix (const char *default_prefix)
+{
+ char *dir1, *dir2;
+
+ if (exe == (char *) NULL) {
+ /* BinReloc not initialized. */
+ if (default_prefix != (const char *) NULL)
+ return strdup (default_prefix);
+ else
+ return (char *) NULL;
+ }
+
+ dir1 = br_dirname (exe);
+ dir2 = br_dirname (dir1);
+ free (dir1);
+ return dir2;
+}
+
+
+/** Locate the application's binary folder.
+ *
+ * The path is generated by the following pseudo-code evaluation:
+ * \code
+ * prefix + "/bin"
+ * \endcode
+ *
+ * @param default_bin_dir A default path which will used as fallback.
+ * @return A string containing the bin folder's path, which must be freed when
+ * no longer necessary. If BinReloc is not initialized, or if
+ * the initialization function failed, then a copy of default_bin_dir will
+ * be returned. If default_bin_dir is NULL, then NULL will be returned.
+ */
+char *
+br_find_bin_dir (const char *default_bin_dir)
+{
+ char *prefix, *dir;
+
+ prefix = br_find_prefix ((const char *) NULL);
+ if (prefix == (char *) NULL) {
+ /* BinReloc not initialized. */
+ if (default_bin_dir != (const char *) NULL)
+ return strdup (default_bin_dir);
+ else
+ return (char *) NULL;
+ }
+
+ dir = br_build_path (prefix, "bin");
+ free (prefix);
+ return dir;
+}
+
+
+/** Locate the application's superuser binary folder.
+ *
+ * The path is generated by the following pseudo-code evaluation:
+ * \code
+ * prefix + "/sbin"
+ * \endcode
+ *
+ * @param default_sbin_dir A default path which will used as fallback.
+ * @return A string containing the sbin folder's path, which must be freed when
+ * no longer necessary. If BinReloc is not initialized, or if the
+ * initialization function failed, then a copy of default_sbin_dir will
+ * be returned. If default_bin_dir is NULL, then NULL will be returned.
+ */
+char *
+br_find_sbin_dir (const char *default_sbin_dir)
+{
+ char *prefix, *dir;
+
+ prefix = br_find_prefix ((const char *) NULL);
+ if (prefix == (char *) NULL) {
+ /* BinReloc not initialized. */
+ if (default_sbin_dir != (const char *) NULL)
+ return strdup (default_sbin_dir);
+ else
+ return (char *) NULL;
+ }
+
+ dir = br_build_path (prefix, "sbin");
+ free (prefix);
+ return dir;
+}
+
+
+/** Locate the application's data folder.
+ *
+ * The path is generated by the following pseudo-code evaluation:
+ * \code
+ * prefix + "/share"
+ * \endcode
+ *
+ * @param default_data_dir A default path which will used as fallback.
+ * @return A string containing the data folder's path, which must be freed when
+ * no longer necessary. If BinReloc is not initialized, or if the
+ * initialization function failed, then a copy of default_data_dir
+ * will be returned. If default_data_dir is NULL, then NULL will be
+ * returned.
+ */
+char *
+br_find_data_dir (const char *default_data_dir)
+{
+ char *prefix, *dir;
+
+ prefix = br_find_prefix ((const char *) NULL);
+ if (prefix == (char *) NULL) {
+ /* BinReloc not initialized. */
+ if (default_data_dir != (const char *) NULL)
+ return strdup (default_data_dir);
+ else
+ return (char *) NULL;
+ }
+
+ dir = br_build_path (prefix, "share");
+ free (prefix);
+ return dir;
+}
+
+
+/** Locate the application's localization folder.
+ *
+ * The path is generated by the following pseudo-code evaluation:
+ * \code
+ * prefix + "/share/locale"
+ * \endcode
+ *
+ * @param default_locale_dir A default path which will used as fallback.
+ * @return A string containing the localization folder's path, which must be freed when
+ * no longer necessary. If BinReloc is not initialized, or if the
+ * initialization function failed, then a copy of default_locale_dir will be returned.
+ * If default_locale_dir is NULL, then NULL will be returned.
+ */
+char *
+br_find_locale_dir (const char *default_locale_dir)
+{
+ char *data_dir, *dir;
+
+ data_dir = br_find_data_dir ((const char *) NULL);
+ if (data_dir == (char *) NULL) {
+ /* BinReloc not initialized. */
+ if (default_locale_dir != (const char *) NULL)
+ return strdup (default_locale_dir);
+ else
+ return (char *) NULL;
+ }
+
+ dir = br_build_path (data_dir, "locale");
+ free (data_dir);
+ return dir;
+}
+
+
+/** Locate the application's library folder.
+ *
+ * The path is generated by the following pseudo-code evaluation:
+ * \code
+ * prefix + "/lib"
+ * \endcode
+ *
+ * @param default_lib_dir A default path which will used as fallback.
+ * @return A string containing the library folder's path, which must be freed when
+ * no longer necessary. If BinReloc is not initialized, or if the initialization
+ * function failed, then a copy of default_lib_dir will be returned.
+ * If default_lib_dir is NULL, then NULL will be returned.
+ */
+char *
+br_find_lib_dir (const char *default_lib_dir)
+{
+ char *prefix, *dir;
+
+ prefix = br_find_prefix ((const char *) NULL);
+ if (prefix == (char *) NULL) {
+ /* BinReloc not initialized. */
+ if (default_lib_dir != (const char *) NULL)
+ return strdup (default_lib_dir);
+ else
+ return (char *) NULL;
+ }
+
+ dir = br_build_path (prefix, "lib");
+ free (prefix);
+ return dir;
+}
+
+
+/** Locate the application's libexec folder.
+ *
+ * The path is generated by the following pseudo-code evaluation:
+ * \code
+ * prefix + "/libexec"
+ * \endcode
+ *
+ * @param default_libexec_dir A default path which will used as fallback.
+ * @return A string containing the libexec folder's path, which must be freed when
+ * no longer necessary. If BinReloc is not initialized, or if the initialization
+ * function failed, then a copy of default_libexec_dir will be returned.
+ * If default_libexec_dir is NULL, then NULL will be returned.
+ */
+char *
+br_find_libexec_dir (const char *default_libexec_dir)
+{
+ char *prefix, *dir;
+
+ prefix = br_find_prefix ((const char *) NULL);
+ if (prefix == (char *) NULL) {
+ /* BinReloc not initialized. */
+ if (default_libexec_dir != (const char *) NULL)
+ return strdup (default_libexec_dir);
+ else
+ return (char *) NULL;
+ }
+
+ dir = br_build_path (prefix, "libexec");
+ free (prefix);
+ return dir;
+}
+
+
+/** Locate the application's configuration files folder.
+ *
+ * The path is generated by the following pseudo-code evaluation:
+ * \code
+ * prefix + "/etc"
+ * \endcode
+ *
+ * @param default_etc_dir A default path which will used as fallback.
+ * @return A string containing the etc folder's path, which must be freed when
+ * no longer necessary. If BinReloc is not initialized, or if the initialization
+ * function failed, then a copy of default_etc_dir will be returned.
+ * If default_etc_dir is NULL, then NULL will be returned.
+ */
+char *
+br_find_etc_dir (const char *default_etc_dir)
+{
+ char *prefix, *dir;
+
+ prefix = br_find_prefix ((const char *) NULL);
+ if (prefix == (char *) NULL) {
+ /* BinReloc not initialized. */
+ if (default_etc_dir != (const char *) NULL)
+ return strdup (default_etc_dir);
+ else
+ return (char *) NULL;
+ }
+
+ dir = br_build_path (prefix, "etc");
+ free (prefix);
+ return dir;
+}
+
+
+/***********************
+ * Utility functions
+ ***********************/
+
+/** Concatenate str1 and str2 to a newly allocated string.
+ *
+ * @param str1 A string.
+ * @param str2 Another string.
+ * @returns A newly-allocated string. This string should be freed when no longer needed.
+ */
+char *
+br_strcat (const char *str1, const char *str2)
+{
+ char *result;
+ size_t len1, len2;
+
+ if (str1 == NULL)
+ str1 = "";
+ if (str2 == NULL)
+ str2 = "";
+
+ len1 = strlen (str1);
+ len2 = strlen (str2);
+
+ result = (char *) malloc (len1 + len2 + 1);
+ memcpy (result, str1, len1);
+ memcpy (result + len1, str2, len2);
+ result[len1 + len2] = '\0';
+
+ return result;
+}
+
+
+char *
+br_build_path (const char *dir, const char *file)
+{
+ char *dir2, *result;
+ size_t len;
+ int must_free = 0;
+
+ len = strlen (dir);
+ if (len > 0 && dir[len - 1] != '/') {
+ dir2 = br_strcat (dir, "/");
+ must_free = 1;
+ } else
+ dir2 = (char *) dir;
+
+ result = br_strcat (dir2, file);
+ if (must_free)
+ free (dir2);
+ return result;
+}
+
+
+/* Emulates glibc's strndup() */
+static char *
+br_strndup (const char *str, size_t size)
+{
+ char *result = (char *) NULL;
+ size_t len;
+
+ if (str == (const char *) NULL)
+ return (char *) NULL;
+
+ len = strlen (str);
+ if (len == 0)
+ return strdup ("");
+ if (size > len)
+ size = len;
+
+ result = (char *) malloc (len + 1);
+ memcpy (result, str, size);
+ result[size] = '\0';
+ return result;
+}
+
+
+/** Extracts the directory component of a path.
+ *
+ * Similar to g_dirname() or the dirname commandline application.
+ *
+ * Example:
+ * \code
+ * br_dirname ("/usr/local/foobar"); --> Returns: "/usr/local"
+ * \endcode
+ *
+ * @param path A path.
+ * @returns A directory name. This string should be freed when no longer needed.
+ */
+char *
+br_dirname (const char *path)
+{
+ char *end, *result;
+
+ if (path == (const char *) NULL)
+ return (char *) NULL;
+
+ end = strrchr (path, '/');
+ if (end == (const char *) NULL)
+ return strdup (".");
+
+ while (end > path && *end == '/')
+ end--;
+ result = br_strndup (path, end - path + 1);
+ if (result[0] == 0) {
+ free (result);
+ return strdup ("/");
+ } else
+ return result;
+}
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __BINRELOC_C__ */
--- /dev/null
+/*
+ * BinReloc - a library for creating relocatable executables
+ * Written by: Hongli Lai <h.lai@chello.nl>
+ * http://autopackage.org/
+ *
+ * This source code is public domain. You can relicense this code
+ * under whatever license you want.
+ *
+ * See http://autopackage.org/docs/binreloc/ for
+ * more information and how to use this.
+ */
+
+#ifndef __BINRELOC_H__
+#define __BINRELOC_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/** These error codes can be returned by br_init(), br_init_lib(), gbr_init() or gbr_init_lib(). */
+typedef enum {
+ /** Cannot allocate memory. */
+ BR_INIT_ERROR_NOMEM,
+ /** Unable to open /proc/self/maps; see errno for details. */
+ BR_INIT_ERROR_OPEN_MAPS,
+ /** Unable to read from /proc/self/maps; see errno for details. */
+ BR_INIT_ERROR_READ_MAPS,
+ /** The file format of /proc/self/maps is invalid; kernel bug? */
+ BR_INIT_ERROR_INVALID_MAPS,
+ /** BinReloc is disabled (the ENABLE_BINRELOC macro is not defined). */
+ BR_INIT_ERROR_DISABLED
+} BrInitError;
+
+
+#ifndef BINRELOC_RUNNING_DOXYGEN
+/* Mangle symbol names to avoid symbol collisions with other ELF objects. */
+ #define br_init PTeH3518859728963_br_init
+ #define br_init_lib PTeH3518859728963_br_init_lib
+ #define br_find_exe PTeH3518859728963_br_find_exe
+ #define br_find_exe_dir PTeH3518859728963_br_find_exe_dir
+ #define br_find_prefix PTeH3518859728963_br_find_prefix
+ #define br_find_bin_dir PTeH3518859728963_br_find_bin_dir
+ #define br_find_sbin_dir PTeH3518859728963_br_find_sbin_dir
+ #define br_find_data_dir PTeH3518859728963_br_find_data_dir
+ #define br_find_locale_dir PTeH3518859728963_br_find_locale_dir
+ #define br_find_lib_dir PTeH3518859728963_br_find_lib_dir
+ #define br_find_libexec_dir PTeH3518859728963_br_find_libexec_dir
+ #define br_find_etc_dir PTeH3518859728963_br_find_etc_dir
+ #define br_strcat PTeH3518859728963_br_strcat
+ #define br_build_path PTeH3518859728963_br_build_path
+ #define br_dirname PTeH3518859728963_br_dirname
+
+
+#endif
+int br_init (BrInitError *error);
+int br_init_lib (BrInitError *error);
+
+char *br_find_exe (const char *default_exe);
+char *br_find_exe_dir (const char *default_dir);
+char *br_find_prefix (const char *default_prefix);
+char *br_find_bin_dir (const char *default_bin_dir);
+char *br_find_sbin_dir (const char *default_sbin_dir);
+char *br_find_data_dir (const char *default_data_dir);
+char *br_find_locale_dir (const char *default_locale_dir);
+char *br_find_lib_dir (const char *default_lib_dir);
+char *br_find_libexec_dir (const char *default_libexec_dir);
+char *br_find_etc_dir (const char *default_etc_dir);
+
+/* Utility functions */
+char *br_strcat (const char *str1, const char *str2);
+char *br_build_path (const char *dir, const char *file);
+char *br_dirname (const char *path);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __BINRELOC_H__ */
--- /dev/null
+/* obstack.c - subroutines used implicitly by object stack macros
+ Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998,
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C 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.
+
+ The GNU C 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 the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "obstack.h"
+
+/* NOTE BEFORE MODIFYING THIS FILE: This version number must be
+ incremented whenever callers compiled using an old obstack.h can no
+ longer properly call the functions in this obstack.c. */
+#define OBSTACK_INTERFACE_VERSION 1
+
+#include <stdio.h> /* Random thing to get __GNU_LIBRARY__. */
+#include <stddef.h>
+#include <stdint.h>
+
+/* Determine default alignment. */
+union fooround
+{
+ uintmax_t i;
+ long double d;
+ void *p;
+};
+struct fooalign
+{
+ char c;
+ union fooround u;
+};
+/* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT.
+ But in fact it might be less smart and round addresses to as much as
+ DEFAULT_ROUNDING. So we prepare for it to do that. */
+enum
+ {
+ DEFAULT_ALIGNMENT = offsetof (struct fooalign, u),
+ DEFAULT_ROUNDING = sizeof (union fooround)
+ };
+
+/* When we copy a long block of data, this is the unit to do it with.
+ On some machines, copying successive ints does not work;
+ in such a case, redefine COPYING_UNIT to `long' (if that works)
+ or `char' as a last resort. */
+# ifndef COPYING_UNIT
+# define COPYING_UNIT int
+# endif
+
+
+/* The functions allocating more room by calling `obstack_chunk_alloc'
+ jump to the handler pointed to by `obstack_alloc_failed_handler'.
+ This can be set to a user defined function which should either
+ abort gracefully or use longjump - but shouldn't return. This
+ variable by default points to the internal function
+ `print_and_abort'. */
+static void print_and_abort (void);
+void (*obstack_alloc_failed_handler) (void) = print_and_abort;
+
+/* Exit value used when `print_and_abort' is used. */
+# include <stdlib.h>
+int obstack_exit_failure = EXIT_FAILURE;
+
+/* Define a macro that either calls functions with the traditional malloc/free
+ calling interface, or calls functions with the mmalloc/mfree interface
+ (that adds an extra first argument), based on the state of use_extra_arg.
+ For free, do not use ?:, since some compilers, like the MIPS compilers,
+ do not allow (expr) ? void : void. */
+
+# define CALL_CHUNKFUN(h, size) \
+ (((h) -> use_extra_arg) \
+ ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
+ : (*(struct _obstack_chunk *(*) (long)) (h)->chunkfun) ((size)))
+
+# define CALL_FREEFUN(h, old_chunk) \
+ do { \
+ if ((h) -> use_extra_arg) \
+ (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
+ else \
+ (*(void (*) (void *)) (h)->freefun) ((old_chunk)); \
+ } while (0)
+
+/* Initialize an obstack H for use. Specify chunk size SIZE (0 means default).
+ Objects start on multiples of ALIGNMENT (0 means use default).
+ CHUNKFUN is the function to use to allocate chunks,
+ and FREEFUN the function to free them.
+
+ Return nonzero if successful, calls obstack_alloc_failed_handler if
+ allocation fails. */
+
+int
+_obstack_begin (struct obstack *h,
+ int size, int alignment,
+ void *(*chunkfun) (long),
+ void (*freefun) (void *))
+{
+ register struct _obstack_chunk *chunk; /* points to new chunk */
+
+ if (alignment == 0)
+ alignment = DEFAULT_ALIGNMENT;
+ if (size == 0)
+ /* Default size is what GNU malloc can fit in a 4096-byte block. */
+ {
+ /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
+ Use the values for range checking, because if range checking is off,
+ the extra bytes won't be missed terribly, but if range checking is on
+ and we used a larger request, a whole extra 4096 bytes would be
+ allocated.
+
+ These number are irrelevant to the new GNU malloc. I suspect it is
+ less sensitive to the size of the request. */
+ int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
+ + 4 + DEFAULT_ROUNDING - 1)
+ & ~(DEFAULT_ROUNDING - 1));
+ size = 4096 - extra;
+ }
+
+ h->chunkfun = (struct _obstack_chunk * (*)(void *, long)) chunkfun;
+ h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
+ h->chunk_size = size;
+ h->alignment_mask = alignment - 1;
+ h->use_extra_arg = 0;
+
+ chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
+ if (!chunk)
+ (*obstack_alloc_failed_handler) ();
+ h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents,
+ alignment - 1);
+ h->chunk_limit = chunk->limit
+ = (char *) chunk + h->chunk_size;
+ chunk->prev = 0;
+ /* The initial chunk now contains no empty object. */
+ h->maybe_empty_object = 0;
+ h->alloc_failed = 0;
+ return 1;
+}
+
+int
+_obstack_begin_1 (struct obstack *h, int size, int alignment,
+ void *(*chunkfun) (void *, long),
+ void (*freefun) (void *, void *),
+ void *arg)
+{
+ register struct _obstack_chunk *chunk; /* points to new chunk */
+
+ if (alignment == 0)
+ alignment = DEFAULT_ALIGNMENT;
+ if (size == 0)
+ /* Default size is what GNU malloc can fit in a 4096-byte block. */
+ {
+ /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
+ Use the values for range checking, because if range checking is off,
+ the extra bytes won't be missed terribly, but if range checking is on
+ and we used a larger request, a whole extra 4096 bytes would be
+ allocated.
+
+ These number are irrelevant to the new GNU malloc. I suspect it is
+ less sensitive to the size of the request. */
+ int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
+ + 4 + DEFAULT_ROUNDING - 1)
+ & ~(DEFAULT_ROUNDING - 1));
+ size = 4096 - extra;
+ }
+
+ h->chunkfun = (struct _obstack_chunk * (*)(void *,long)) chunkfun;
+ h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
+ h->chunk_size = size;
+ h->alignment_mask = alignment - 1;
+ h->extra_arg = arg;
+ h->use_extra_arg = 1;
+
+ chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
+ if (!chunk)
+ (*obstack_alloc_failed_handler) ();
+ h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents,
+ alignment - 1);
+ h->chunk_limit = chunk->limit
+ = (char *) chunk + h->chunk_size;
+ chunk->prev = 0;
+ /* The initial chunk now contains no empty object. */
+ h->maybe_empty_object = 0;
+ h->alloc_failed = 0;
+ return 1;
+}
+
+/* Allocate a new current chunk for the obstack *H
+ on the assumption that LENGTH bytes need to be added
+ to the current object, or a new object of length LENGTH allocated.
+ Copies any partial object from the end of the old chunk
+ to the beginning of the new one. */
+
+void
+_obstack_newchunk (struct obstack *h, int length)
+{
+ register struct _obstack_chunk *old_chunk = h->chunk;
+ register struct _obstack_chunk *new_chunk;
+ register long new_size;
+ register long obj_size = h->next_free - h->object_base;
+ register long i;
+ long already;
+ char *object_base;
+
+ /* Compute size for new chunk. */
+ new_size = (obj_size + length) + (obj_size >> 3) + h->alignment_mask + 100;
+ if (new_size < h->chunk_size)
+ new_size = h->chunk_size;
+
+ /* Allocate and initialize the new chunk. */
+ new_chunk = CALL_CHUNKFUN (h, new_size);
+ if (!new_chunk)
+ (*obstack_alloc_failed_handler) ();
+ h->chunk = new_chunk;
+ new_chunk->prev = old_chunk;
+ new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;
+
+ /* Compute an aligned object_base in the new chunk */
+ object_base =
+ __PTR_ALIGN ((char *) new_chunk, new_chunk->contents, h->alignment_mask);
+
+ /* Move the existing object to the new chunk.
+ Word at a time is fast and is safe if the object
+ is sufficiently aligned. */
+ if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT)
+ {
+ for (i = obj_size / sizeof (COPYING_UNIT) - 1;
+ i >= 0; i--)
+ ((COPYING_UNIT *)object_base)[i]
+ = ((COPYING_UNIT *)h->object_base)[i];
+ /* We used to copy the odd few remaining bytes as one extra COPYING_UNIT,
+ but that can cross a page boundary on a machine
+ which does not do strict alignment for COPYING_UNITS. */
+ already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT);
+ }
+ else
+ already = 0;
+ /* Copy remaining bytes one by one. */
+ for (i = already; i < obj_size; i++)
+ object_base[i] = h->object_base[i];
+
+ /* If the object just copied was the only data in OLD_CHUNK,
+ free that chunk and remove it from the chain.
+ But not if that chunk might contain an empty object. */
+ if (! h->maybe_empty_object
+ && (h->object_base
+ == __PTR_ALIGN ((char *) old_chunk, old_chunk->contents,
+ h->alignment_mask)))
+ {
+ new_chunk->prev = old_chunk->prev;
+ CALL_FREEFUN (h, old_chunk);
+ }
+
+ h->object_base = object_base;
+ h->next_free = h->object_base + obj_size;
+ /* The new chunk certainly contains no empty object yet. */
+ h->maybe_empty_object = 0;
+}
+
+/* Return nonzero if object OBJ has been allocated from obstack H.
+ This is here for debugging.
+ If you use it in a program, you are probably losing. */
+
+/* Suppress -Wmissing-prototypes warning. We don't want to declare this in
+ obstack.h because it is just for debugging. */
+int _obstack_allocated_p (struct obstack *h, void *obj);
+
+int
+_obstack_allocated_p (struct obstack *h, void *obj)
+{
+ register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
+ register struct _obstack_chunk *plp; /* point to previous chunk if any */
+
+ lp = (h)->chunk;
+ /* We use >= rather than > since the object cannot be exactly at
+ the beginning of the chunk but might be an empty object exactly
+ at the end of an adjacent chunk. */
+ while (lp != 0 && ((void *) lp >= obj || (void *) (lp)->limit < obj))
+ {
+ plp = lp->prev;
+ lp = plp;
+ }
+ return lp != 0;
+}
+
+/* Free objects in obstack H, including OBJ and everything allocate
+ more recently than OBJ. If OBJ is zero, free everything in H. */
+
+# undef obstack_free
+
+void
+obstack_free (struct obstack *h, void *obj)
+{
+ register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
+ register struct _obstack_chunk *plp; /* point to previous chunk if any */
+
+ lp = h->chunk;
+ /* We use >= because there cannot be an object at the beginning of a chunk.
+ But there can be an empty object at that address
+ at the end of another chunk. */
+ while (lp != 0 && ((void *) lp >= obj || (void *) (lp)->limit < obj))
+ {
+ plp = lp->prev;
+ CALL_FREEFUN (h, lp);
+ lp = plp;
+ /* If we switch chunks, we can't tell whether the new current
+ chunk contains an empty object, so assume that it may. */
+ h->maybe_empty_object = 1;
+ }
+ if (lp)
+ {
+ h->object_base = h->next_free = (char *) (obj);
+ h->chunk_limit = lp->limit;
+ h->chunk = lp;
+ }
+ else if (obj != 0)
+ /* obj is not in any of the chunks! */
+ abort ();
+}
+
+int
+_obstack_memory_used (struct obstack *h)
+{
+ register struct _obstack_chunk* lp;
+ register int nbytes = 0;
+
+ for (lp = h->chunk; lp != 0; lp = lp->prev)
+ {
+ nbytes += lp->limit - (char *) lp;
+ }
+ return nbytes;
+}
+
+static void
+__attribute__ ((noreturn))
+print_and_abort (void)
+{
+ /* Don't change any of these strings. Yes, it would be possible to add
+ the newline to the string and use fputs or so. But this must not
+ happen because the "memory exhausted" message appears in other places
+ like this and the translation should be reused instead of creating
+ a very similar string which requires a separate translation. */
+ fprintf (stderr, "%s\n", "memory exhausted");
+ exit (obstack_exit_failure);
+}
+
--- /dev/null
+/* obstack.h - object stack macros
+ Copyright (C) 1988-1994,1996-1999,2003,2004,2005
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C 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.
+
+ The GNU C 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 the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+/* Summary:
+
+All the apparent functions defined here are macros. The idea
+is that you would use these pre-tested macros to solve a
+very specific set of problems, and they would run fast.
+Caution: no side-effects in arguments please!! They may be
+evaluated MANY times!!
+
+These macros operate a stack of objects. Each object starts life
+small, and may grow to maturity. (Consider building a word syllable
+by syllable.) An object can move while it is growing. Once it has
+been "finished" it never changes address again. So the "top of the
+stack" is typically an immature growing object, while the rest of the
+stack is of mature, fixed size and fixed address objects.
+
+These routines grab large chunks of memory, using a function you
+supply, called `obstack_chunk_alloc'. On occasion, they free chunks,
+by calling `obstack_chunk_free'. You must define them and declare
+them before using any obstack macros.
+
+Each independent stack is represented by a `struct obstack'.
+Each of the obstack macros expects a pointer to such a structure
+as the first argument.
+
+One motivation for this package is the problem of growing char strings
+in symbol tables. Unless you are "fascist pig with a read-only mind"
+--Gosper's immortal quote from HAKMEM item 154, out of context--you
+would not like to put any arbitrary upper limit on the length of your
+symbols.
+
+In practice this often means you will build many short symbols and a
+few long symbols. At the time you are reading a symbol you don't know
+how long it is. One traditional method is to read a symbol into a
+buffer, realloc()ating the buffer every time you try to read a symbol
+that is longer than the buffer. This is beaut, but you still will
+want to copy the symbol from the buffer to a more permanent
+symbol-table entry say about half the time.
+
+With obstacks, you can work differently. Use one obstack for all symbol
+names. As you read a symbol, grow the name in the obstack gradually.
+When the name is complete, finalize it. Then, if the symbol exists already,
+free the newly read name.
+
+The way we do this is to take a large chunk, allocating memory from
+low addresses. When you want to build a symbol in the chunk you just
+add chars above the current "high water mark" in the chunk. When you
+have finished adding chars, because you got to the end of the symbol,
+you know how long the chars are, and you can create a new object.
+Mostly the chars will not burst over the highest address of the chunk,
+because you would typically expect a chunk to be (say) 100 times as
+long as an average object.
+
+In case that isn't clear, when we have enough chars to make up
+the object, THEY ARE ALREADY CONTIGUOUS IN THE CHUNK (guaranteed)
+so we just point to it where it lies. No moving of chars is
+needed and this is the second win: potentially long strings need
+never be explicitly shuffled. Once an object is formed, it does not
+change its address during its lifetime.
+
+When the chars burst over a chunk boundary, we allocate a larger
+chunk, and then copy the partly formed object from the end of the old
+chunk to the beginning of the new larger chunk. We then carry on
+accreting characters to the end of the object as we normally would.
+
+A special macro is provided to add a single char at a time to a
+growing object. This allows the use of register variables, which
+break the ordinary 'growth' macro.
+
+Summary:
+ We allocate large chunks.
+ We carve out one object at a time from the current chunk.
+ Once carved, an object never moves.
+ We are free to append data of any size to the currently
+ growing object.
+ Exactly one object is growing in an obstack at any one time.
+ You can run one obstack per control block.
+ You may have as many control blocks as you dare.
+ Because of the way we do it, you can `unwind' an obstack
+ back to a previous state. (You may remove objects much
+ as you would with a stack.)
+*/
+
+
+/* Don't do the contents of this file more than once. */
+
+#ifndef _OBSTACK_H
+#define _OBSTACK_H 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* We need the type of a pointer subtraction. If __PTRDIFF_TYPE__ is
+ defined, as with GNU C, use that; that way we don't pollute the
+ namespace with <stddef.h>'s symbols. Otherwise, include <stddef.h>
+ and use ptrdiff_t. */
+
+#ifdef __PTRDIFF_TYPE__
+# define PTR_INT_TYPE __PTRDIFF_TYPE__
+#else
+# include <stddef.h>
+# define PTR_INT_TYPE ptrdiff_t
+#endif
+
+/* If B is the base of an object addressed by P, return the result of
+ aligning P to the next multiple of A + 1. B and P must be of type
+ char *. A + 1 must be a power of 2. */
+
+#define __BPTR_ALIGN(B, P, A) ((B) + (((P) - (B) + (A)) & ~(A)))
+
+/* Similar to _BPTR_ALIGN (B, P, A), except optimize the common case
+ where pointers can be converted to integers, aligned as integers,
+ and converted back again. If PTR_INT_TYPE is narrower than a
+ pointer (e.g., the AS/400), play it safe and compute the alignment
+ relative to B. Otherwise, use the faster strategy of computing the
+ alignment relative to 0. */
+
+#define __PTR_ALIGN(B, P, A) \
+ __BPTR_ALIGN (sizeof (PTR_INT_TYPE) < sizeof (void *) ? (B) : (char *) 0, \
+ P, A)
+
+#include <string.h>
+
+struct _obstack_chunk /* Lives at front of each chunk. */
+{
+ char *limit; /* 1 past end of this chunk */
+ struct _obstack_chunk *prev; /* address of prior chunk or NULL */
+ char contents[4]; /* objects begin here */
+};
+
+struct obstack /* control current object in current chunk */
+{
+ long chunk_size; /* preferred size to allocate chunks in */
+ struct _obstack_chunk *chunk; /* address of current struct obstack_chunk */
+ char *object_base; /* address of object we are building */
+ char *next_free; /* where to add next char to current object */
+ char *chunk_limit; /* address of char after current chunk */
+ union
+ {
+ PTR_INT_TYPE tempint;
+ void *tempptr;
+ } temp; /* Temporary for some macros. */
+ int alignment_mask; /* Mask of alignment for each object. */
+ /* These prototypes vary based on `use_extra_arg', and we use
+ casts to the prototypeless function type in all assignments,
+ but having prototypes here quiets -Wstrict-prototypes. */
+ struct _obstack_chunk *(*chunkfun) (void *, long);
+ void (*freefun) (void *, struct _obstack_chunk *);
+ void *extra_arg; /* first arg for chunk alloc/dealloc funcs */
+ unsigned use_extra_arg:1; /* chunk alloc/dealloc funcs take extra arg */
+ unsigned maybe_empty_object:1;/* There is a possibility that the current
+ chunk contains a zero-length object. This
+ prevents freeing the chunk if we allocate
+ a bigger chunk to replace it. */
+ unsigned alloc_failed:1; /* No longer used, as we now call the failed
+ handler on error, but retained for binary
+ compatibility. */
+};
+
+/* Declare the external functions we use; they are in obstack.c. */
+
+extern void _obstack_newchunk (struct obstack *, int);
+extern int _obstack_begin (struct obstack *, int, int,
+ void *(*) (long), void (*) (void *));
+extern int _obstack_begin_1 (struct obstack *, int, int,
+ void *(*) (void *, long),
+ void (*) (void *, void *), void *);
+extern int _obstack_memory_used (struct obstack *);
+
+void obstack_free (struct obstack *obstack, void *block);
+
+
+/* Error handler called when `obstack_chunk_alloc' failed to allocate
+ more memory. This can be set to a user defined function which
+ should either abort gracefully or use longjump - but shouldn't
+ return. The default action is to print a message and abort. */
+extern void (*obstack_alloc_failed_handler) (void);
+
+/* Exit value used when `print_and_abort' is used. */
+extern int obstack_exit_failure;
+
+/* Pointer to beginning of object being allocated or to be allocated next.
+ Note that this might not be the final address of the object
+ because a new chunk might be needed to hold the final size. */
+
+#define obstack_base(h) ((void *) (h)->object_base)
+
+/* Size for allocating ordinary chunks. */
+
+#define obstack_chunk_size(h) ((h)->chunk_size)
+
+/* Pointer to next byte not yet allocated in current chunk. */
+
+#define obstack_next_free(h) ((h)->next_free)
+
+/* Mask specifying low bits that should be clear in address of an object. */
+
+#define obstack_alignment_mask(h) ((h)->alignment_mask)
+
+/* To prevent prototype warnings provide complete argument list. */
+#define obstack_init(h) \
+ _obstack_begin ((h), 0, 0, \
+ (void *(*) (long)) obstack_chunk_alloc, \
+ (void (*) (void *)) obstack_chunk_free)
+
+#define obstack_begin(h, size) \
+ _obstack_begin ((h), (size), 0, \
+ (void *(*) (long)) obstack_chunk_alloc, \
+ (void (*) (void *)) obstack_chunk_free)
+
+#define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \
+ _obstack_begin ((h), (size), (alignment), \
+ (void *(*) (long)) (chunkfun), \
+ (void (*) (void *)) (freefun))
+
+#define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \
+ _obstack_begin_1 ((h), (size), (alignment), \
+ (void *(*) (void *, long)) (chunkfun), \
+ (void (*) (void *, void *)) (freefun), (arg))
+
+#define obstack_chunkfun(h, newchunkfun) \
+ ((h) -> chunkfun = (struct _obstack_chunk *(*)(void *, long)) (newchunkfun))
+
+#define obstack_freefun(h, newfreefun) \
+ ((h) -> freefun = (void (*)(void *, struct _obstack_chunk *)) (newfreefun))
+
+#define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = (achar))
+
+#define obstack_blank_fast(h,n) ((h)->next_free += (n))
+
+#define obstack_memory_used(h) _obstack_memory_used (h)
+
+#if defined __GNUC__ && defined __STDC__ && __STDC__
+/* NextStep 2.0 cc is really gcc 1.93 but it defines __GNUC__ = 2 and
+ does not implement __extension__. But that compiler doesn't define
+ __GNUC_MINOR__. */
+# if __GNUC__ < 2 || (__NeXT__ && !__GNUC_MINOR__)
+# define __extension__
+# endif
+
+/* For GNU C, if not -traditional,
+ we can define these macros to compute all args only once
+ without using a global variable.
+ Also, we can avoid using the `temp' slot, to make faster code. */
+
+# define obstack_object_size(OBSTACK) \
+ __extension__ \
+ ({ struct obstack const *__o = (OBSTACK); \
+ (unsigned) (__o->next_free - __o->object_base); })
+
+# define obstack_room(OBSTACK) \
+ __extension__ \
+ ({ struct obstack const *__o = (OBSTACK); \
+ (unsigned) (__o->chunk_limit - __o->next_free); })
+
+# define obstack_make_room(OBSTACK,length) \
+__extension__ \
+({ struct obstack *__o = (OBSTACK); \
+ int __len = (length); \
+ if (__o->chunk_limit - __o->next_free < __len) \
+ _obstack_newchunk (__o, __len); \
+ (void) 0; })
+
+# define obstack_empty_p(OBSTACK) \
+ __extension__ \
+ ({ struct obstack const *__o = (OBSTACK); \
+ (__o->chunk->prev == 0 \
+ && __o->next_free == __PTR_ALIGN ((char *) __o->chunk, \
+ __o->chunk->contents, \
+ __o->alignment_mask)); })
+
+# define obstack_grow(OBSTACK,where,length) \
+__extension__ \
+({ struct obstack *__o = (OBSTACK); \
+ int __len = (length); \
+ if (__o->next_free + __len > __o->chunk_limit) \
+ _obstack_newchunk (__o, __len); \
+ memcpy (__o->next_free, where, __len); \
+ __o->next_free += __len; \
+ (void) 0; })
+
+# define obstack_grow0(OBSTACK,where,length) \
+__extension__ \
+({ struct obstack *__o = (OBSTACK); \
+ int __len = (length); \
+ if (__o->next_free + __len + 1 > __o->chunk_limit) \
+ _obstack_newchunk (__o, __len + 1); \
+ memcpy (__o->next_free, where, __len); \
+ __o->next_free += __len; \
+ *(__o->next_free)++ = 0; \
+ (void) 0; })
+
+# define obstack_1grow(OBSTACK,datum) \
+__extension__ \
+({ struct obstack *__o = (OBSTACK); \
+ if (__o->next_free + 1 > __o->chunk_limit) \
+ _obstack_newchunk (__o, 1); \
+ obstack_1grow_fast (__o, datum); \
+ (void) 0; })
+
+/* These assume that the obstack alignment is good enough for pointers
+ or ints, and that the data added so far to the current object
+ shares that much alignment. */
+
+# define obstack_ptr_grow(OBSTACK,datum) \
+__extension__ \
+({ struct obstack *__o = (OBSTACK); \
+ if (__o->next_free + sizeof (void *) > __o->chunk_limit) \
+ _obstack_newchunk (__o, sizeof (void *)); \
+ obstack_ptr_grow_fast (__o, datum); }) \
+
+# define obstack_int_grow(OBSTACK,datum) \
+__extension__ \
+({ struct obstack *__o = (OBSTACK); \
+ if (__o->next_free + sizeof (int) > __o->chunk_limit) \
+ _obstack_newchunk (__o, sizeof (int)); \
+ obstack_int_grow_fast (__o, datum); })
+
+# define obstack_ptr_grow_fast(OBSTACK,aptr) \
+__extension__ \
+({ struct obstack *__o1 = (OBSTACK); \
+ *(const void **) __o1->next_free = (aptr); \
+ __o1->next_free += sizeof (const void *); \
+ (void) 0; })
+
+# define obstack_int_grow_fast(OBSTACK,aint) \
+__extension__ \
+({ struct obstack *__o1 = (OBSTACK); \
+ *(int *) __o1->next_free = (aint); \
+ __o1->next_free += sizeof (int); \
+ (void) 0; })
+
+# define obstack_blank(OBSTACK,length) \
+__extension__ \
+({ struct obstack *__o = (OBSTACK); \
+ int __len = (length); \
+ if (__o->chunk_limit - __o->next_free < __len) \
+ _obstack_newchunk (__o, __len); \
+ obstack_blank_fast (__o, __len); \
+ (void) 0; })
+
+# define obstack_alloc(OBSTACK,length) \
+__extension__ \
+({ struct obstack *__h = (OBSTACK); \
+ obstack_blank (__h, (length)); \
+ obstack_finish (__h); })
+
+# define obstack_copy(OBSTACK,where,length) \
+__extension__ \
+({ struct obstack *__h = (OBSTACK); \
+ obstack_grow (__h, (where), (length)); \
+ obstack_finish (__h); })
+
+# define obstack_copy0(OBSTACK,where,length) \
+__extension__ \
+({ struct obstack *__h = (OBSTACK); \
+ obstack_grow0 (__h, (where), (length)); \
+ obstack_finish (__h); })
+
+/* The local variable is named __o1 to avoid a name conflict
+ when obstack_blank is called. */
+# define obstack_finish(OBSTACK) \
+__extension__ \
+({ struct obstack *__o1 = (OBSTACK); \
+ void *__value = (void *) __o1->object_base; \
+ if (__o1->next_free == __value) \
+ __o1->maybe_empty_object = 1; \
+ __o1->next_free \
+ = __PTR_ALIGN (__o1->object_base, __o1->next_free, \
+ __o1->alignment_mask); \
+ if (__o1->next_free - (char *)__o1->chunk \
+ > __o1->chunk_limit - (char *)__o1->chunk) \
+ __o1->next_free = __o1->chunk_limit; \
+ __o1->object_base = __o1->next_free; \
+ __value; })
+
+# define obstack_free(OBSTACK, OBJ) \
+__extension__ \
+({ struct obstack *__o = (OBSTACK); \
+ void *__obj = (OBJ); \
+ if (__obj > (void *)__o->chunk && __obj < (void *)__o->chunk_limit) \
+ __o->next_free = __o->object_base = (char *)__obj; \
+ else (obstack_free) (__o, __obj); })
+
+#else /* not __GNUC__ or not __STDC__ */
+
+# define obstack_object_size(h) \
+ (unsigned) ((h)->next_free - (h)->object_base)
+
+# define obstack_room(h) \
+ (unsigned) ((h)->chunk_limit - (h)->next_free)
+
+# define obstack_empty_p(h) \
+ ((h)->chunk->prev == 0 \
+ && (h)->next_free == __PTR_ALIGN ((char *) (h)->chunk, \
+ (h)->chunk->contents, \
+ (h)->alignment_mask))
+
+/* Note that the call to _obstack_newchunk is enclosed in (..., 0)
+ so that we can avoid having void expressions
+ in the arms of the conditional expression.
+ Casting the third operand to void was tried before,
+ but some compilers won't accept it. */
+
+# define obstack_make_room(h,length) \
+( (h)->temp.tempint = (length), \
+ (((h)->next_free + (h)->temp.tempint > (h)->chunk_limit) \
+ ? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0))
+
+# define obstack_grow(h,where,length) \
+( (h)->temp.tempint = (length), \
+ (((h)->next_free + (h)->temp.tempint > (h)->chunk_limit) \
+ ? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0), \
+ memcpy ((h)->next_free, where, (h)->temp.tempint), \
+ (h)->next_free += (h)->temp.tempint)
+
+# define obstack_grow0(h,where,length) \
+( (h)->temp.tempint = (length), \
+ (((h)->next_free + (h)->temp.tempint + 1 > (h)->chunk_limit) \
+ ? (_obstack_newchunk ((h), (h)->temp.tempint + 1), 0) : 0), \
+ memcpy ((h)->next_free, where, (h)->temp.tempint), \
+ (h)->next_free += (h)->temp.tempint, \
+ *((h)->next_free)++ = 0)
+
+# define obstack_1grow(h,datum) \
+( (((h)->next_free + 1 > (h)->chunk_limit) \
+ ? (_obstack_newchunk ((h), 1), 0) : 0), \
+ obstack_1grow_fast (h, datum))
+
+# define obstack_ptr_grow(h,datum) \
+( (((h)->next_free + sizeof (char *) > (h)->chunk_limit) \
+ ? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0), \
+ obstack_ptr_grow_fast (h, datum))
+
+# define obstack_int_grow(h,datum) \
+( (((h)->next_free + sizeof (int) > (h)->chunk_limit) \
+ ? (_obstack_newchunk ((h), sizeof (int)), 0) : 0), \
+ obstack_int_grow_fast (h, datum))
+
+# define obstack_ptr_grow_fast(h,aptr) \
+ (((const void **) ((h)->next_free += sizeof (void *)))[-1] = (aptr))
+
+# define obstack_int_grow_fast(h,aint) \
+ (((int *) ((h)->next_free += sizeof (int)))[-1] = (aint))
+
+# define obstack_blank(h,length) \
+( (h)->temp.tempint = (length), \
+ (((h)->chunk_limit - (h)->next_free < (h)->temp.tempint) \
+ ? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0), \
+ obstack_blank_fast (h, (h)->temp.tempint))
+
+# define obstack_alloc(h,length) \
+ (obstack_blank ((h), (length)), obstack_finish ((h)))
+
+# define obstack_copy(h,where,length) \
+ (obstack_grow ((h), (where), (length)), obstack_finish ((h)))
+
+# define obstack_copy0(h,where,length) \
+ (obstack_grow0 ((h), (where), (length)), obstack_finish ((h)))
+
+# define obstack_finish(h) \
+( ((h)->next_free == (h)->object_base \
+ ? (((h)->maybe_empty_object = 1), 0) \
+ : 0), \
+ (h)->temp.tempptr = (h)->object_base, \
+ (h)->next_free \
+ = __PTR_ALIGN ((h)->object_base, (h)->next_free, \
+ (h)->alignment_mask), \
+ (((h)->next_free - (char *) (h)->chunk \
+ > (h)->chunk_limit - (char *) (h)->chunk) \
+ ? ((h)->next_free = (h)->chunk_limit) : 0), \
+ (h)->object_base = (h)->next_free, \
+ (h)->temp.tempptr)
+
+# define obstack_free(h,obj) \
+( (h)->temp.tempint = (char *) (obj) - (char *) (h)->chunk, \
+ ((((h)->temp.tempint > 0 \
+ && (h)->temp.tempint < (h)->chunk_limit - (char *) (h)->chunk)) \
+ ? (int) ((h)->next_free = (h)->object_base \
+ = (h)->temp.tempint + (char *) (h)->chunk) \
+ : (((obstack_free) ((h), (h)->temp.tempint + (char *) (h)->chunk), 0), 0)))
+
+#endif /* not __GNUC__ or not __STDC__ */
+
+#ifdef __cplusplus
+} /* C++ */
+#endif
+
+#endif /* obstack.h */
--- /dev/null
+#
+# SuperTux - squirrel library build script
+# Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
+#
+# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+## Add include/ to include directories
+
+INCLUDE_DIRECTORIES(${SUPERTUX_SOURCE_DIR}/external/squirrel/include/)
+
+## build list of source files
+
+FILE(GLOB SQUIRREL_SOURCES squirrel/*.cpp sqstdlib/*.cpp sqstdlib/*.c)
+
+# the squirrel sources are out of our control so don't be too pedantic about
+# them
+REMOVE_DEFINITIONS(-Werror -W)
+
+## define a target for building the library
+
+ADD_LIBRARY(squirrel ${SQUIRREL_SOURCES})
--- /dev/null
+Copyright (c) 2003-2009 Alberto Demichelis\r
+\r
+This software is provided 'as-is', without any \r
+express or implied warranty. In no event will the \r
+authors be held liable for any damages arising from \r
+the use of this software.\r
+\r
+Permission is granted to anyone to use this software \r
+for any purpose, including commercial applications, \r
+and to alter it and redistribute it freely, subject \r
+to the following restrictions:\r
+\r
+ 1. The origin of this software must not be \r
+ misrepresented; you must not claim that \r
+ you wrote the original software. If you \r
+ use this software in a product, an \r
+ acknowledgment in the product \r
+ documentation would be appreciated but is \r
+ not required.\r
+\r
+ 2. Altered source versions must be plainly \r
+ marked as such, and must not be \r
+ misrepresented as being the original \r
+ software.\r
+\r
+ 3. This notice may not be removed or \r
+ altered from any source distribution.\r
+-----------------------------------------------------\r
+END OF COPYRIGHT
\ No newline at end of file
--- /dev/null
+***version 2.2.3 stable***\r
+-added sq_getfunctioninfo\r
+-added compile time flag SQUSEDOUBLE to use double precision floats\r
+-added global slot _floatsize_ int the base lib to recognize single precision and double precision builds\r
+-sq_wakeupvm can now resume the vm with an exception\r
+-added sqstd_format\r
+-generators can now be instantiated by calling sq_call() or closure.call()\r
+-fixed a bug in sqstd_printcallstack(thx takayuki_h)\r
+-fixed modulo by zero(thx jup)\r
+-fixed negative enums and constants\r
+-fixed generator crash bug if invoked as tail call (thx Mr.Accident)\r
+-fixed some minor bug\r
+\r
+***2008-09-24 ***\r
+***version 2.2.2 stable***\r
+-fixed some behaviour inconsistencies in thread.call() and thread.wakeup() (thx Mr.Accident)\r
+-fixed coroutine error propagation\r
+-fixed lingering return value from native function (thx Tom Leonard)\r
+-fixed a bug if array.sort() is given a bad sort function (thx Tom Leonard)\r
+-fixed some minor api bug\r
+-added sq_arrayremove() and sq_arrayinsert()\r
+\r
+***2008-05-16 ***\r
+***version 2.2.1 stable***\r
+-fixed a tailcall bug\r
+\r
+***2008-02-17 ***\r
+***version 2.2 stable ***\r
+-added _newslot metamethod in classes\r
+-added enums added constants\r
+-added sq_pushconsttable, sq_setconsttable\r
+-added default param\r
+-added octal literals(thx Dinosaur)\r
+-fixed debug hook, 'calls' and 'returns' are properly notified in the same number.\r
+-fixed a coroutine bug\r
+\r
+***2007-07-29 ***\r
+***version 2.1.2 stable***\r
+-new behaviour for generators iteration using foreach\r
+now when a generator is iterated by foreach the value returned by a 'return val' statement\r
+will terminate the iteration but will not be returned as foreach iteration\r
+-added sq_setclassudsize()\r
+-added sq_clear()\r
+-added table.clear(), array.clear()\r
+-fixed sq_cmp() (thx jyuill)\r
+-fixed minor bugs\r
+\r
+***2006-08-21 ***\r
+***version 2.1.1 stable***\r
+-vm refactoring\r
+-optimized internal function memory layout\r
+-new global symbol _version_ (is the version string)\r
+-code size optimization for float literals(on 32bits float builts)\r
+-now the raw ref API(sq_addref etc...) is fully reentrant.\r
+-fixed a bug in sq_getdelegate() now pushes null if the object doesn't have a delegate(thx MatzeB)\r
+-improved C reference performances in NO_GARBAGE_COLLECTOR builds\r
+-sq_getlocal() now enumerates also outer values.\r
+-fixed regexp library for GCC users.\r
+\r
+***2006-03-19 ***\r
+***version 2.1 stable***\r
+-added static class fields, new keyword static\r
+-added 64bits architecture support\r
+-added global slot _intsize_ int the base lib to recognize 32bits and 64bits builds\r
+-added functions with fixed environment, closure.bindenv() built-in function\r
+-all types except userdata and null implement the tostring() method\r
+-string concatenation now invokes metamethod _tostring\r
+-new metamethods for class objects _newmember and _inherited\r
+-sq_call() sq_resume() sq_wakeupvm() have a new signature\r
+-new C referencing implementation(scales more with the amount of references)\r
+-refactored hash table\r
+-new api functions sq_newslot(),sq_tobool(),sq_getbase(), sq_instanceof(), sq_bindenv()\r
+-the api func sq_createslot was deprecated but still supported in form of C macro on top of sq_newslot\r
+-sq_setreleasehook() now also works for classes\r
+-stream.readstr() and stream.writestr() have been deprecated(this affects file and blob)\r
+-fixed squirrel.h undeclared api calls\r
+-fixed few minor bugs\r
+-SQChar is now defined as wchar_t\r
+-removed warning when building with -Wall -pedantic for GCC users\r
+-added new std io function writeclosuretofile()\r
+-added new std string functions strip(),rstrip(),lstrip() and split()\r
+-regular expressions operators (+,*) now have more POSIX greedyness behaviour\r
+-class constructors are now invoked as normal functions\r
+\r
+***2005-10-02 ***\r
+***version 2.0.5 stable***\r
+-fixed some 64bits incompatibilities (thx sarge)\r
+-fixed minor bug in the stdlib format() function (thx Rick)\r
+-fixed a bug in dofile() that was preventing to compile empty files\r
+-added new API sq_poptop() & sq_getfreevariable()\r
+-some performance improvements\r
+\r
+***2005-08-14 ***\r
+***version 2.0.4 stable***\r
+-weak references and related API calls\r
+-added sq_objtobool()\r
+-class instances memory policies improved(1 mem allocation for the whole instance)\r
+-typetags are now declared as SQUserPointer instead of unsigned int\r
+-first pass for 64bits compatibility\r
+-fixed minor bug in the stdio stream\r
+-fixed a bug in format()\r
+-fixed bug in string.tointeger() and string.tofloat()\r
+\r
+***2005-06-24 ***\r
+***version 2.0.3 stable***\r
+-dofile() and loadfile() in the iolib now can decode ASCII, UTF8 files UCS2 big-endian and little-endian\r
+-sq_setparamscheck() : now typemesk can check for null\r
+-added string escape sequence \xhhhh\r
+-fixed some C++ standard incompatibilities\r
+\r
+***2005-05-15 ***\r
+***version 2.0.2 stable***\r
+-performances improvements (expecially for GCC users)\r
+-removed all dependencies from C++ exception handling\r
+-various bugfixes\r
+\r
+***2005-04-12 ***\r
+***version 2.0.1 stable***\r
+-various bugfixes\r
+-sq_setparamscheck() now allows spaces in the typemask\r
+\r
+***2005-04-03 ***\r
+***version 2.0 stable***\r
+-added API sq_gettypetag()\r
+-added built-in function to the bool type(tointeger, tostring etc...)\r
+\r
+***2005-02-27 ***\r
+***version 2.0 release candidate 1(RC 1)***\r
+-added API sq_reseterror()\r
+-modified sq_release()\r
+-now class instances can be cloned\r
+-various bufixes\r
+\r
+***2005-01-26 ***\r
+***version 2.0 beta 1***\r
+-added bool type\r
+-class properties can be redefined in a derived class\r
+-added ops *= /= and %=\r
+-new syntax for class attributes declaration </ and /> instead of ( and )\r
+-increased the max number of literals per function from 65535 to 16777215\r
+-now free variables have proper lexical scoping\r
+-added API sq_createinstance(), sq_pushbool(), sq_getbool()\r
+-added built-in function type()\r
+-added built-in function obj.rawin(key) in table,class and instance\r
+-sq_rawget() and sq_rawset() now work also on classes and instances\r
+-the VM no longer uses C++ exception handling (more suitable for embedded devices)\r
+-various bufixes\r
+\r
+***2004-12-21 ***\r
+***version 2.0 alpha 2***\r
+-globals scoping changed, now if :: is omitted the VM automatically falls back on the root table\r
+-various bufixes\r
+-added class level attributes\r
+\r
+***2004-12-12 ***\r
+***version 2.0 alpha 1***\r
+-codebase branch from version 1.x\r
+-added classes\r
+-added functions with variable number of parameters(vargc & vargv and the ...)\r
+-0 and 0.0 are now considered 'false' by all conditional statements(if,while,for,?,do-while)\r
+-added new api functions sq_newclass() sq_setinstanceup() sq_getinstanceup() sq_getattributes() sq_setattributes()\r
+-modified api sq_settypetag()\r
+\r
+***2004-11-01 ***\r
+***version 1.0 stable***\r
+-fixed some minor bug\r
+-improoved operator 'delete' performances\r
+-added scientific notation for float numbers( eg. 2.e16 or 2.e-2)\r
+\r
+***2004-08-30 ***\r
+***version 1.0 release candidate 2(RC 2)***\r
+-fixed bug in the vm(thx Pierre Renaux)\r
+-fixed bug in the optimizer(thx Pierre Renaux)\r
+-fixed some bug in the documentation(thx JD)\r
+-added new api functions for raw object handling\r
+-removed nested multiline comments\r
+-reduced memory footprint in C references\r
+\r
+***2004-08-23 ***\r
+***version 1.0 release candidate 1(RC 1)***\r
+-fixed division by zero\r
+-the 'in' operator and obj.rawget() do not query the default delegate anymore\r
+-added function sq_getprintfunc()\r
+-added new standard library 'auxlib'(implements default error handlers)\r
+\r
+***2004-07-12 ***\r
+***version 1.0 beta 4***\r
+-fixed a bug in the integer.tochar() built-in method\r
+-fixed unary minus operator\r
+-fixed bug in dofile()\r
+-fixed inconsistency between != and == operators(on float/integer comparison)\r
+-added javascript style unsigned right shift operator '>>>'\r
+-added array(size) constructor built-in function\r
+-array.resize(size,[fill]) built-in function accepts an optional 'fill' value\r
+-improved debug API, added sq_getclosureinfo() and sq_setnativeclosurename()\r
+\r
+***2004-05-23 ***\r
+***version 1.0 beta 3***\r
+-minor vm bug fixes\r
+-string allocation is now faster\r
+-tables and array memory usage is now less conservative(they shrink)\r
+-added regular expression routines in the standard library\r
+-The 'c' expression now accepts only 1 character(thx irbrian)\r
+-multiline strings <[ ]> have been substituted with C# style verbatim strings (eg. @"string")\r
+-added new keyword 'parent' for accessing the delegate of tables and unserdata\r
+-The metamethod '_clone' has been renamed '_cloned'\r
+-the _delslot metamethod's behaviour and prototype have been changed\r
+-new default function in the integer and float object 'tochar()'\r
+-the built-in function chcode2string has been removed\r
+-the default method [table].getdelegate() has been removed\r
+-new api sq_rawdeleteslot()\r
+-new table built-in method rawdelete(key)\r
+-the dynamic mudule loading has been removed from the standard distribution\r
+-some optimizations in the VM\r
+\r
+***2004-04-21 ***\r
+***version 1.0 beta 2***\r
+-minor compiler/parser bug fixes\r
+-sq_newclosure has a different prototype, the "paramscheck" of paramter has been moved to the new function sq_setparamscheck()\r
+-sq_setparamscheck allows to add automatic parameters type checking in native closures\r
+-sq_compile() lost the lineinfo parameter\r
+-new api sq_enabledebuginfo() globally sets compiler's debug info generation\r
+-added consistency check on bytecode serialization\r
+-fixed += operator, now works on strings like +\r
+-added global slot in the base lib _charsize_ to recognize unicode builds from ascii builds runtime\r
+-added registry table\r
+-new api call sq_pushregistrytable()\r
+-added type tag to the userdata type sq_settypetag()\r
+-sq_getuserdata now queries the userdata typetag\r
+-the built in function collect_garbage() as been renamed collectgarbage() for consistency reasons\r
+-new standard libraries(sqlibs are now obsolete)\r
+\r
+***2004-02-20 ***\r
+***version 1.0 beta 1***\r
+-fixed a bug in the compiler (thanks Martin Kofler)\r
+-fixed bug in the switch case statement\r
+-fixed the _unm metamethod\r
+-fixed minor bugs in the API\r
+-fixed automatic stack resizing\r
+-first beta version \r
+ first pass code clean up in the VM and base lib\r
+ first pass code coverege test has been done on VM and built-in lib\r
+-new VM creation API sq_open() sq_close() (sq_newvm and sq_releasevm are now obsolete)\r
+-new api allows to specifiy a "print" function to output text(sq_printfunc)\r
+-added some small optimizations\r
+-new cooperative multi-threading capabilities in the base library(coroutines), VMs are now a built in type("thread")\r
+-new built in functions have been added for manipulating the new "thread" type\r
+-friend virtual machines share the same root table, error handler and debug hook by default\r
+-new compile time options\r
+\r
+***2004-01-19 ***\r
+***version 0.9 alpha***\r
+-fixed a garbage collection bug\r
+-fixed some API bugs(thanks to Joshua Jensen)\r
+-fixed tail calls (in the version 0.8 the tail call optimization was erroneously disabled)\r
+-new function parameters semantic, now passing a wrong number of parameters generates an exception\r
+-native closures have now a built in parameter number checking\r
+-sq_rawget and sq_rawset now work also on arrays\r
+-sq_getsize now woks also on userdata\r
+-the userdata release hook prototype is changed(now passes the size of the userdata)\r
+-the lexer reader function now returns an integer instead of a char that allows better error checking on the input(thx Joshua Jensen)\r
+-faster compiler\r
+-try/catch blocks do not cause any runtime memory allocation anymore\r
+\r
+***2003-12-06 ***\r
+***version 0.8 alpha***\r
+-fixed a bug that was preventing to have callable userdata throught the metamethod _call\r
+-fixed a garbage collection bug\r
+-fixed == operator now can compare correctly different types\r
+-new built in method getstackinfos(level)\r
+-improoved line informations precision for the debug hook\r
+-new api call sq_compilebuffer()\r
+-new built-in api function compilestring()\r
+-new syntactic sugar for function declarations inside tables\r
+-the debug API has been finalized\r
+\r
+***2003-11-17 ***\r
+***version 0.7 alpha***\r
+-fixed critical bug SQInteger the tail call system\r
+-fixed bug in the continue statement code generation\r
+-fixed func call param issue(thanks to Rewoonenco Andrew)\r
+-added _delslot metamethod(thanks to Rewoonenco Andrew)\r
+-new multiline string expression ( delimited by <[ and ]> )\r
+-normal strings ("") do not allow embedded new line anymore\r
+-reduced vm memory footprint(C refs are shared between friend VMs)\r
+-new api method sq_deleteslot()\r
+-new debug hook event 'r' is triggered when a function returns\r
+\r
+***2003-11-04 ***\r
+***version 0.6 alpha***\r
+-fixed switch statement(was executing the default case after a break)\r
+-sq_call() doesn't pop the closure (just the params)\r
+-the vm execution can be suspended from the C API anytime (micro-threads)\r
+-new api calls sq_suspendvm() sq_wakeupvm() sq_getvmstate() and sq_reservestack()\r
+\r
+***2003-10-13 ***\r
+***version 0.5 alpha***\r
+-fixed some minor bug\r
+-tested with non ASCII identifiers in unicode mode(I've tried chinese chars)\r
+-added built-in function string.find()\r
+-the built-in function array.sort() optionally accepts a cmp(a,b) function\r
+-the debug hook function now has a new prototype debug_hook(event_type,sourcefile,line,functionname)\r
+-fixed some debug info imprecision\r
+\r
+***2003-10-01 ***\r
+***version 0.4 alpha***\r
+-faster VM\r
+-sq_call will pop arguments and closure also in case of failure\r
+-fixed a bug in sq_remove\r
+-now the VM detects delegation cycles(and throws an exception)\r
+-new operators ++ and --\r
+-new operator ',' comma operator\r
+-fixed some expression precedence issue\r
+-fixed bug in sq_arraypop\r
+\r
+***2003-09-15 ***\r
+***version 0.3 alpha***\r
+-fixed a bug in array::insert()\r
+-optional Unicode core(define SQUNICODE or _UNICODE on Win32)\r
+-sq_compiler uses a new reader function SQLEXREADFUNC\r
+-the debug hook passes 'l' instead of 'line' for line callbacks\r
+ and 'c' instead of 'call' for call callbacks\r
+-new array.extend() bulit-in function\r
+-new API sq_clone()\r
+\r
+***2003-09-10 ***\r
+***version 0.2 pre-alpha***\r
+-new completely reentrant VM (sq_open and sq_close are now obsolete)\r
+-sq_newvm() has a new prototype\r
+-allocators are now global and linked in the VM\r
+-_newslot meta method added\r
+-rawset creates a slot if doesn't exists\r
+-the compiler error callback pass the vm handle(thanks Pierre Renaux)\r
+-sq_setforeignptr() sq_getforeingptr() are now public\r
+-sq_resume() now is possible to resume generators from C\r
+-sq_getlasterror() retrieve the last thrown error\r
+-improved docs\r
+\r
+***2003-09-06 ***\r
+***version 0.1 pre-alpha***\r
+first release\r
--- /dev/null
+The programming language SQUIRREL 2.2.3 stable\r
+\r
+--------------------------------------------------\r
+The project has been compiled and run on Windows(Windows XP/2000 on Intel x86 Windows XP Pro on AMD x64) and\r
+Linux(Slackware 9.0 on Intel x86, Fedora Core 4 on AMD x64).\r
+\r
+Has been tested with the following compilers:\r
+ MS Visual C++ 6.0,7.0,7.1 and 8.0 (32 and 64bits)\r
+ MinGW gcc 3.2 (mingw special 20020817-1)\r
+ Cygnus gcc 3.2\r
+ Linux gcc 3.2.3\r
+ Linux gcc 4.0.0 (x86 64bits)\r
+ \r
+\r
+Feedback and suggestions are appreciated \r
+project page - http://www.squirrel-lang.org\r
+community forums - http://www.squirrel-lang.org/Forums\r
+wiki - http://wiki.squirrel-lang.org\r
+author - alberto@demichelis.net\r
+\r
+END OF README\r
+\r
--- /dev/null
+/* see copyright notice in squirrel.h */
+#ifndef _SQSTD_AUXLIB_H_
+#define _SQSTD_AUXLIB_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+SQUIRREL_API void sqstd_seterrorhandlers(HSQUIRRELVM v);
+SQUIRREL_API void sqstd_printcallstack(HSQUIRRELVM v);
+
+#ifdef __cplusplus
+} /*extern "C"*/
+#endif
+
+#endif /* _SQSTD_AUXLIB_H_ */
--- /dev/null
+/* see copyright notice in squirrel.h */
+#ifndef _SQSTDBLOB_H_
+#define _SQSTDBLOB_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+SQUIRREL_API SQUserPointer sqstd_createblob(HSQUIRRELVM v, SQInteger size);
+SQUIRREL_API SQRESULT sqstd_getblob(HSQUIRRELVM v,SQInteger idx,SQUserPointer *ptr);
+SQUIRREL_API SQInteger sqstd_getblobsize(HSQUIRRELVM v,SQInteger idx);
+
+SQUIRREL_API SQRESULT sqstd_register_bloblib(HSQUIRRELVM v);
+
+#ifdef __cplusplus
+} /*extern "C"*/
+#endif
+
+#endif /*_SQSTDBLOB_H_*/
+
--- /dev/null
+/* see copyright notice in squirrel.h */
+#ifndef _SQSTDIO_H_
+#define _SQSTDIO_H_
+
+#ifdef __cplusplus
+
+#define SQSTD_STREAM_TYPE_TAG 0x80000000
+
+struct SQStream {
+ virtual ~SQStream() {}
+ virtual SQInteger Read(void *buffer, SQInteger size) = 0;
+ virtual SQInteger Write(void *buffer, SQInteger size) = 0;
+ virtual SQInteger Flush() = 0;
+ virtual SQInteger Tell() = 0;
+ virtual SQInteger Len() = 0;
+ virtual SQInteger Seek(SQInteger offset, SQInteger origin) = 0;
+ virtual bool IsValid() = 0;
+ virtual bool EOS() = 0;
+};
+
+extern "C" {
+#endif
+
+#define SQ_SEEK_CUR 0
+#define SQ_SEEK_END 1
+#define SQ_SEEK_SET 2
+
+typedef void* SQFILE;
+
+SQUIRREL_API SQFILE sqstd_fopen(const SQChar *,const SQChar *);
+SQUIRREL_API SQInteger sqstd_fread(SQUserPointer, SQInteger, SQInteger, SQFILE);
+SQUIRREL_API SQInteger sqstd_fwrite(const SQUserPointer, SQInteger, SQInteger, SQFILE);
+SQUIRREL_API SQInteger sqstd_fseek(SQFILE , SQInteger , SQInteger);
+SQUIRREL_API SQInteger sqstd_ftell(SQFILE);
+SQUIRREL_API SQInteger sqstd_fflush(SQFILE);
+SQUIRREL_API SQInteger sqstd_fclose(SQFILE);
+SQUIRREL_API SQInteger sqstd_feof(SQFILE);
+
+SQUIRREL_API SQRESULT sqstd_createfile(HSQUIRRELVM v, SQFILE file,SQBool own);
+SQUIRREL_API SQRESULT sqstd_getfile(HSQUIRRELVM v, SQInteger idx, SQFILE *file);
+
+//compiler helpers
+SQUIRREL_API SQRESULT sqstd_loadfile(HSQUIRRELVM v,const SQChar *filename,SQBool printerror);
+SQUIRREL_API SQRESULT sqstd_dofile(HSQUIRRELVM v,const SQChar *filename,SQBool retval,SQBool printerror);
+SQUIRREL_API SQRESULT sqstd_writeclosuretofile(HSQUIRRELVM v,const SQChar *filename);
+
+SQUIRREL_API SQRESULT sqstd_register_iolib(HSQUIRRELVM v);
+
+#ifdef __cplusplus
+} /*extern "C"*/
+#endif
+
+#endif /*_SQSTDIO_H_*/
+
--- /dev/null
+/* see copyright notice in squirrel.h */
+#ifndef _SQSTD_MATH_H_
+#define _SQSTD_MATH_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+SQUIRREL_API SQRESULT sqstd_register_mathlib(HSQUIRRELVM v);
+
+#ifdef __cplusplus
+} /*extern "C"*/
+#endif
+
+#endif /*_SQSTD_MATH_H_*/
--- /dev/null
+/* see copyright notice in squirrel.h */
+#ifndef _SQSTD_STRING_H_
+#define _SQSTD_STRING_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef unsigned int SQRexBool;
+typedef struct SQRex SQRex;
+
+typedef struct {
+ const SQChar *begin;
+ SQInteger len;
+} SQRexMatch;
+
+SQUIRREL_API SQRex *sqstd_rex_compile(const SQChar *pattern,const SQChar **error);
+SQUIRREL_API void sqstd_rex_free(SQRex *exp);
+SQUIRREL_API SQBool sqstd_rex_match(SQRex* exp,const SQChar* text);
+SQUIRREL_API SQBool sqstd_rex_search(SQRex* exp,const SQChar* text, const SQChar** out_begin, const SQChar** out_end);
+SQUIRREL_API SQBool sqstd_rex_searchrange(SQRex* exp,const SQChar* text_begin,const SQChar* text_end,const SQChar** out_begin, const SQChar** out_end);
+SQUIRREL_API SQInteger sqstd_rex_getsubexpcount(SQRex* exp);
+SQUIRREL_API SQBool sqstd_rex_getsubexp(SQRex* exp, SQInteger n, SQRexMatch *subexp);
+
+SQUIRREL_API SQRESULT sqstd_format(HSQUIRRELVM v,SQInteger nformatstringidx,SQInteger *outlen,SQChar **output);
+
+SQUIRREL_API SQRESULT sqstd_register_stringlib(HSQUIRRELVM v);
+
+#ifdef __cplusplus
+} /*extern "C"*/
+#endif
+
+#endif /*_SQSTD_STRING_H_*/
--- /dev/null
+/* see copyright notice in squirrel.h */
+#ifndef _SQSTD_SYSTEMLIB_H_
+#define _SQSTD_SYSTEMLIB_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+SQUIRREL_API SQInteger sqstd_register_systemlib(HSQUIRRELVM v);
+
+#ifdef __cplusplus
+} /*extern "C"*/
+#endif
+
+#endif /* _SQSTD_SYSTEMLIB_H_ */
--- /dev/null
+/*
+Copyright (c) 2003-2009 Alberto Demichelis
+
+This software is provided 'as-is', without any
+express or implied warranty. In no event will the
+authors be held liable for any damages arising from
+the use of this software.
+
+Permission is granted to anyone to use this software
+for any purpose, including commercial applications,
+and to alter it and redistribute it freely, subject
+to the following restrictions:
+
+ 1. The origin of this software must not be
+ misrepresented; you must not claim that
+ you wrote the original software. If you
+ use this software in a product, an
+ acknowledgment in the product
+ documentation would be appreciated but is
+ not required.
+
+ 2. Altered source versions must be plainly
+ marked as such, and must not be
+ misrepresented as being the original
+ software.
+
+ 3. This notice may not be removed or
+ altered from any source distribution.
+
+*/
+#ifndef _SQUIRREL_H_
+#define _SQUIRREL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef SQUIRREL_API
+#define SQUIRREL_API extern
+#endif
+
+#if (defined(_WIN64) || defined(_LP64))
+#define _SQ64
+#endif
+
+#ifdef _SQ64
+#ifdef _MSC_VER
+typedef __int64 SQInteger;
+typedef unsigned __int64 SQUnsignedInteger;
+typedef unsigned __int64 SQHash; /*should be the same size of a pointer*/
+#else
+typedef long SQInteger;
+typedef unsigned long SQUnsignedInteger;
+typedef unsigned long SQHash; /*should be the same size of a pointer*/
+#endif
+typedef int SQInt32;
+#else
+typedef int SQInteger;
+typedef int SQInt32; /*must be 32 bits(also on 64bits processors)*/
+typedef unsigned int SQUnsignedInteger;
+typedef unsigned int SQHash; /*should be the same size of a pointer*/
+#endif
+
+
+#ifdef SQUSEDOUBLE
+typedef double SQFloat;
+#else
+typedef float SQFloat;
+#endif
+
+#if defined(SQUSEDOUBLE) && !defined(_SQ64)
+#ifdef _MSC_VER
+typedef __int64 SQRawObjectVal; //must be 64bits
+#else
+typedef long SQRawObjectVal; //must be 64bits
+#endif
+#define SQ_OBJECT_RAWINIT() { _unVal.raw = 0; }
+#else
+typedef SQUnsignedInteger SQRawObjectVal; //is 32 bits on 32 bits builds and 64 bits otherwise
+#define SQ_OBJECT_RAWINIT()
+#endif
+
+typedef void* SQUserPointer;
+typedef SQUnsignedInteger SQBool;
+typedef SQInteger SQRESULT;
+
+#define SQTrue (1)
+#define SQFalse (0)
+
+struct SQVM;
+struct SQTable;
+struct SQArray;
+struct SQString;
+struct SQClosure;
+struct SQGenerator;
+struct SQNativeClosure;
+struct SQUserData;
+struct SQFunctionProto;
+struct SQRefCounted;
+struct SQClass;
+struct SQInstance;
+struct SQDelegable;
+
+#ifdef _UNICODE
+#define SQUNICODE
+#endif
+
+#ifdef SQUNICODE
+#if (defined(_MSC_VER) && _MSC_VER >= 1400) // 1400 = VS8
+
+#if defined(wchar_t) //this is if the compiler considers wchar_t as native type
+#define wchar_t unsigned short
+#endif
+
+#else
+typedef unsigned short wchar_t;
+#endif
+
+typedef wchar_t SQChar;
+#define _SC(a) L##a
+#define scstrcmp wcscmp
+#define scsprintf swprintf
+#define scstrlen wcslen
+#define scstrtod wcstod
+#define scstrtol wcstol
+#define scatoi _wtoi
+#define scstrtoul wcstoul
+#define scvsprintf vswprintf
+#define scstrstr wcsstr
+#define scisspace iswspace
+#define scisdigit iswdigit
+#define scisxdigit iswxdigit
+#define scisalpha iswalpha
+#define sciscntrl iswcntrl
+#define scisalnum iswalnum
+#define scprintf wprintf
+#define MAX_CHAR 0xFFFF
+#else
+typedef char SQChar;
+#define _SC(a) a
+#define scstrcmp strcmp
+#define scsprintf sprintf
+#define scstrlen strlen
+#define scstrtod strtod
+#define scstrtol strtol
+#define scatoi atoi
+#define scstrtoul strtoul
+#define scvsprintf vsprintf
+#define scstrstr strstr
+#define scisspace isspace
+#define scisdigit isdigit
+#define scisxdigit isxdigit
+#define sciscntrl iscntrl
+#define scisalpha isalpha
+#define scisalnum isalnum
+#define scprintf printf
+#define MAX_CHAR 0xFF
+#endif
+
+#define SQUIRREL_VERSION _SC("Squirrel 2.2.3 stable")
+#define SQUIRREL_COPYRIGHT _SC("Copyright (C) 2003-2009 Alberto Demichelis")
+#define SQUIRREL_AUTHOR _SC("Alberto Demichelis")
+
+#define SQ_VMSTATE_IDLE 0
+#define SQ_VMSTATE_RUNNING 1
+#define SQ_VMSTATE_SUSPENDED 2
+
+#define SQUIRREL_EOB 0
+#define SQ_BYTECODE_STREAM_TAG 0xFAFA
+
+#define SQOBJECT_REF_COUNTED 0x08000000
+#define SQOBJECT_NUMERIC 0x04000000
+#define SQOBJECT_DELEGABLE 0x02000000
+#define SQOBJECT_CANBEFALSE 0x01000000
+
+#define SQ_MATCHTYPEMASKSTRING (-99999)
+
+#define _RT_MASK 0x00FFFFFF
+#define _RAW_TYPE(type) (type&_RT_MASK)
+
+#define _RT_NULL 0x00000001
+#define _RT_INTEGER 0x00000002
+#define _RT_FLOAT 0x00000004
+#define _RT_BOOL 0x00000008
+#define _RT_STRING 0x00000010
+#define _RT_TABLE 0x00000020
+#define _RT_ARRAY 0x00000040
+#define _RT_USERDATA 0x00000080
+#define _RT_CLOSURE 0x00000100
+#define _RT_NATIVECLOSURE 0x00000200
+#define _RT_GENERATOR 0x00000400
+#define _RT_USERPOINTER 0x00000800
+#define _RT_THREAD 0x00001000
+#define _RT_FUNCPROTO 0x00002000
+#define _RT_CLASS 0x00004000
+#define _RT_INSTANCE 0x00008000
+#define _RT_WEAKREF 0x00010000
+
+typedef enum tagSQObjectType{
+ OT_NULL = (_RT_NULL|SQOBJECT_CANBEFALSE),
+ OT_INTEGER = (_RT_INTEGER|SQOBJECT_NUMERIC|SQOBJECT_CANBEFALSE),
+ OT_FLOAT = (_RT_FLOAT|SQOBJECT_NUMERIC|SQOBJECT_CANBEFALSE),
+ OT_BOOL = (_RT_BOOL|SQOBJECT_CANBEFALSE),
+ OT_STRING = (_RT_STRING|SQOBJECT_REF_COUNTED),
+ OT_TABLE = (_RT_TABLE|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE),
+ OT_ARRAY = (_RT_ARRAY|SQOBJECT_REF_COUNTED),
+ OT_USERDATA = (_RT_USERDATA|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE),
+ OT_CLOSURE = (_RT_CLOSURE|SQOBJECT_REF_COUNTED),
+ OT_NATIVECLOSURE = (_RT_NATIVECLOSURE|SQOBJECT_REF_COUNTED),
+ OT_GENERATOR = (_RT_GENERATOR|SQOBJECT_REF_COUNTED),
+ OT_USERPOINTER = _RT_USERPOINTER,
+ OT_THREAD = (_RT_THREAD|SQOBJECT_REF_COUNTED) ,
+ OT_FUNCPROTO = (_RT_FUNCPROTO|SQOBJECT_REF_COUNTED), //internal usage only
+ OT_CLASS = (_RT_CLASS|SQOBJECT_REF_COUNTED),
+ OT_INSTANCE = (_RT_INSTANCE|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE),
+ OT_WEAKREF = (_RT_WEAKREF|SQOBJECT_REF_COUNTED)
+}SQObjectType;
+
+#define ISREFCOUNTED(t) (t&SQOBJECT_REF_COUNTED)
+
+
+typedef union tagSQObjectValue
+{
+ struct SQTable *pTable;
+ struct SQArray *pArray;
+ struct SQClosure *pClosure;
+ struct SQGenerator *pGenerator;
+ struct SQNativeClosure *pNativeClosure;
+ struct SQString *pString;
+ struct SQUserData *pUserData;
+ SQInteger nInteger;
+ SQFloat fFloat;
+ SQUserPointer pUserPointer;
+ struct SQFunctionProto *pFunctionProto;
+ struct SQRefCounted *pRefCounted;
+ struct SQDelegable *pDelegable;
+ struct SQVM *pThread;
+ struct SQClass *pClass;
+ struct SQInstance *pInstance;
+ struct SQWeakRef *pWeakRef;
+ SQRawObjectVal raw;
+}SQObjectValue;
+
+
+typedef struct tagSQObject
+{
+ SQObjectType _type;
+ SQObjectValue _unVal;
+}SQObject;
+
+typedef struct tagSQStackInfos{
+ const SQChar* funcname;
+ const SQChar* source;
+ SQInteger line;
+}SQStackInfos;
+
+typedef struct SQVM* HSQUIRRELVM;
+typedef SQObject HSQOBJECT;
+typedef SQInteger (*SQFUNCTION)(HSQUIRRELVM);
+typedef SQInteger (*SQRELEASEHOOK)(SQUserPointer,SQInteger size);
+typedef void (*SQCOMPILERERROR)(HSQUIRRELVM,const SQChar * /*desc*/,const SQChar * /*source*/,SQInteger /*line*/,SQInteger /*column*/);
+typedef void (*SQPRINTFUNCTION)(HSQUIRRELVM,const SQChar * ,...);
+
+typedef SQInteger (*SQWRITEFUNC)(SQUserPointer,SQUserPointer,SQInteger);
+typedef SQInteger (*SQREADFUNC)(SQUserPointer,SQUserPointer,SQInteger);
+
+typedef SQInteger (*SQLEXREADFUNC)(SQUserPointer);
+
+typedef struct tagSQRegFunction{
+ const SQChar *name;
+ SQFUNCTION f;
+ SQInteger nparamscheck;
+ const SQChar *typemask;
+}SQRegFunction;
+
+typedef struct tagSQFunctionInfo {
+ SQUserPointer funcid;
+ const SQChar *name;
+ const SQChar *source;
+}SQFunctionInfo;
+
+
+/*vm*/
+SQUIRREL_API HSQUIRRELVM sq_open(SQInteger initialstacksize);
+SQUIRREL_API HSQUIRRELVM sq_newthread(HSQUIRRELVM friendvm, SQInteger initialstacksize);
+SQUIRREL_API void sq_seterrorhandler(HSQUIRRELVM v);
+SQUIRREL_API void sq_close(HSQUIRRELVM v);
+SQUIRREL_API void sq_setforeignptr(HSQUIRRELVM v,SQUserPointer p);
+SQUIRREL_API SQUserPointer sq_getforeignptr(HSQUIRRELVM v);
+SQUIRREL_API void sq_setprintfunc(HSQUIRRELVM v, SQPRINTFUNCTION printfunc);
+SQUIRREL_API SQPRINTFUNCTION sq_getprintfunc(HSQUIRRELVM v);
+SQUIRREL_API SQRESULT sq_suspendvm(HSQUIRRELVM v);
+SQUIRREL_API SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool resumedret,SQBool retval,SQBool raiseerror,SQBool throwerror);
+SQUIRREL_API SQInteger sq_getvmstate(HSQUIRRELVM v);
+
+/*compiler*/
+SQUIRREL_API SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQChar *sourcename,SQBool raiseerror);
+SQUIRREL_API SQRESULT sq_compilebuffer(HSQUIRRELVM v,const SQChar *s,SQInteger size,const SQChar *sourcename,SQBool raiseerror);
+SQUIRREL_API void sq_enabledebuginfo(HSQUIRRELVM v, SQBool enable);
+SQUIRREL_API void sq_notifyallexceptions(HSQUIRRELVM v, SQBool enable);
+SQUIRREL_API void sq_setcompilererrorhandler(HSQUIRRELVM v,SQCOMPILERERROR f);
+
+/*stack operations*/
+SQUIRREL_API void sq_push(HSQUIRRELVM v,SQInteger idx);
+SQUIRREL_API void sq_pop(HSQUIRRELVM v,SQInteger nelemstopop);
+SQUIRREL_API void sq_poptop(HSQUIRRELVM v);
+SQUIRREL_API void sq_remove(HSQUIRRELVM v,SQInteger idx);
+SQUIRREL_API SQInteger sq_gettop(HSQUIRRELVM v);
+SQUIRREL_API void sq_settop(HSQUIRRELVM v,SQInteger newtop);
+SQUIRREL_API void sq_reservestack(HSQUIRRELVM v,SQInteger nsize);
+SQUIRREL_API SQInteger sq_cmp(HSQUIRRELVM v);
+SQUIRREL_API void sq_move(HSQUIRRELVM dest,HSQUIRRELVM src,SQInteger idx);
+
+/*object creation handling*/
+SQUIRREL_API SQUserPointer sq_newuserdata(HSQUIRRELVM v,SQUnsignedInteger size);
+SQUIRREL_API void sq_newtable(HSQUIRRELVM v);
+SQUIRREL_API void sq_newarray(HSQUIRRELVM v,SQInteger size);
+SQUIRREL_API void sq_newclosure(HSQUIRRELVM v,SQFUNCTION func,SQUnsignedInteger nfreevars);
+SQUIRREL_API SQRESULT sq_setparamscheck(HSQUIRRELVM v,SQInteger nparamscheck,const SQChar *typemask);
+SQUIRREL_API SQRESULT sq_bindenv(HSQUIRRELVM v,SQInteger idx);
+SQUIRREL_API void sq_pushstring(HSQUIRRELVM v,const SQChar *s,SQInteger len);
+SQUIRREL_API void sq_pushfloat(HSQUIRRELVM v,SQFloat f);
+SQUIRREL_API void sq_pushinteger(HSQUIRRELVM v,SQInteger n);
+SQUIRREL_API void sq_pushbool(HSQUIRRELVM v,SQBool b);
+SQUIRREL_API void sq_pushuserpointer(HSQUIRRELVM v,SQUserPointer p);
+SQUIRREL_API void sq_pushnull(HSQUIRRELVM v);
+SQUIRREL_API SQObjectType sq_gettype(HSQUIRRELVM v,SQInteger idx);
+SQUIRREL_API SQInteger sq_getsize(HSQUIRRELVM v,SQInteger idx);
+SQUIRREL_API SQRESULT sq_getbase(HSQUIRRELVM v,SQInteger idx);
+SQUIRREL_API SQBool sq_instanceof(HSQUIRRELVM v);
+SQUIRREL_API void sq_tostring(HSQUIRRELVM v,SQInteger idx);
+SQUIRREL_API void sq_tobool(HSQUIRRELVM v, SQInteger idx, SQBool *b);
+SQUIRREL_API SQRESULT sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar **c);
+SQUIRREL_API SQRESULT sq_getinteger(HSQUIRRELVM v,SQInteger idx,SQInteger *i);
+SQUIRREL_API SQRESULT sq_getfloat(HSQUIRRELVM v,SQInteger idx,SQFloat *f);
+SQUIRREL_API SQRESULT sq_getbool(HSQUIRRELVM v,SQInteger idx,SQBool *b);
+SQUIRREL_API SQRESULT sq_getthread(HSQUIRRELVM v,SQInteger idx,HSQUIRRELVM *thread);
+SQUIRREL_API SQRESULT sq_getuserpointer(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p);
+SQUIRREL_API SQRESULT sq_getuserdata(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p,SQUserPointer *typetag);
+SQUIRREL_API SQRESULT sq_settypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer typetag);
+SQUIRREL_API SQRESULT sq_gettypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer *typetag);
+SQUIRREL_API void sq_setreleasehook(HSQUIRRELVM v,SQInteger idx,SQRELEASEHOOK hook);
+SQUIRREL_API SQChar *sq_getscratchpad(HSQUIRRELVM v,SQInteger minsize);
+SQUIRREL_API SQRESULT sq_getfunctioninfo(HSQUIRRELVM v,SQInteger idx,SQFunctionInfo *fi);
+SQUIRREL_API SQRESULT sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger *nparams,SQUnsignedInteger *nfreevars);
+SQUIRREL_API SQRESULT sq_setnativeclosurename(HSQUIRRELVM v,SQInteger idx,const SQChar *name);
+SQUIRREL_API SQRESULT sq_setinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer p);
+SQUIRREL_API SQRESULT sq_getinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p,SQUserPointer typetag);
+SQUIRREL_API SQRESULT sq_setclassudsize(HSQUIRRELVM v, SQInteger idx, SQInteger udsize);
+SQUIRREL_API SQRESULT sq_newclass(HSQUIRRELVM v,SQBool hasbase);
+SQUIRREL_API SQRESULT sq_createinstance(HSQUIRRELVM v,SQInteger idx);
+SQUIRREL_API SQRESULT sq_setattributes(HSQUIRRELVM v,SQInteger idx);
+SQUIRREL_API SQRESULT sq_getattributes(HSQUIRRELVM v,SQInteger idx);
+SQUIRREL_API SQRESULT sq_getclass(HSQUIRRELVM v,SQInteger idx);
+SQUIRREL_API void sq_weakref(HSQUIRRELVM v,SQInteger idx);
+SQUIRREL_API SQRESULT sq_getdefaultdelegate(HSQUIRRELVM v,SQObjectType t);
+
+/*object manipulation*/
+SQUIRREL_API void sq_pushroottable(HSQUIRRELVM v);
+SQUIRREL_API void sq_pushregistrytable(HSQUIRRELVM v);
+SQUIRREL_API void sq_pushconsttable(HSQUIRRELVM v);
+SQUIRREL_API SQRESULT sq_setroottable(HSQUIRRELVM v);
+SQUIRREL_API SQRESULT sq_setconsttable(HSQUIRRELVM v);
+SQUIRREL_API SQRESULT sq_newslot(HSQUIRRELVM v, SQInteger idx, SQBool bstatic);
+SQUIRREL_API SQRESULT sq_deleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval);
+SQUIRREL_API SQRESULT sq_set(HSQUIRRELVM v,SQInteger idx);
+SQUIRREL_API SQRESULT sq_get(HSQUIRRELVM v,SQInteger idx);
+SQUIRREL_API SQRESULT sq_rawget(HSQUIRRELVM v,SQInteger idx);
+SQUIRREL_API SQRESULT sq_rawset(HSQUIRRELVM v,SQInteger idx);
+SQUIRREL_API SQRESULT sq_rawdeleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval);
+SQUIRREL_API SQRESULT sq_arrayappend(HSQUIRRELVM v,SQInteger idx);
+SQUIRREL_API SQRESULT sq_arraypop(HSQUIRRELVM v,SQInteger idx,SQBool pushval);
+SQUIRREL_API SQRESULT sq_arrayresize(HSQUIRRELVM v,SQInteger idx,SQInteger newsize);
+SQUIRREL_API SQRESULT sq_arrayreverse(HSQUIRRELVM v,SQInteger idx);
+SQUIRREL_API SQRESULT sq_arrayremove(HSQUIRRELVM v,SQInteger idx,SQInteger itemidx);
+SQUIRREL_API SQRESULT sq_arrayinsert(HSQUIRRELVM v,SQInteger idx,SQInteger destpos);
+SQUIRREL_API SQRESULT sq_setdelegate(HSQUIRRELVM v,SQInteger idx);
+SQUIRREL_API SQRESULT sq_getdelegate(HSQUIRRELVM v,SQInteger idx);
+SQUIRREL_API SQRESULT sq_clone(HSQUIRRELVM v,SQInteger idx);
+SQUIRREL_API SQRESULT sq_setfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval);
+SQUIRREL_API SQRESULT sq_next(HSQUIRRELVM v,SQInteger idx);
+SQUIRREL_API SQRESULT sq_getweakrefval(HSQUIRRELVM v,SQInteger idx);
+SQUIRREL_API SQRESULT sq_clear(HSQUIRRELVM v,SQInteger idx);
+
+/*calls*/
+SQUIRREL_API SQRESULT sq_call(HSQUIRRELVM v,SQInteger params,SQBool retval,SQBool raiseerror);
+SQUIRREL_API SQRESULT sq_resume(HSQUIRRELVM v,SQBool retval,SQBool raiseerror);
+SQUIRREL_API const SQChar *sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedInteger idx);
+SQUIRREL_API const SQChar *sq_getfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval);
+SQUIRREL_API SQRESULT sq_throwerror(HSQUIRRELVM v,const SQChar *err);
+SQUIRREL_API void sq_reseterror(HSQUIRRELVM v);
+SQUIRREL_API void sq_getlasterror(HSQUIRRELVM v);
+
+/*raw object handling*/
+SQUIRREL_API SQRESULT sq_getstackobj(HSQUIRRELVM v,SQInteger idx,HSQOBJECT *po);
+SQUIRREL_API void sq_pushobject(HSQUIRRELVM v,HSQOBJECT obj);
+SQUIRREL_API void sq_addref(HSQUIRRELVM v,HSQOBJECT *po);
+SQUIRREL_API SQBool sq_release(HSQUIRRELVM v,HSQOBJECT *po);
+SQUIRREL_API void sq_resetobject(HSQOBJECT *po);
+SQUIRREL_API const SQChar *sq_objtostring(HSQOBJECT *o);
+SQUIRREL_API SQBool sq_objtobool(HSQOBJECT *o);
+SQUIRREL_API SQInteger sq_objtointeger(HSQOBJECT *o);
+SQUIRREL_API SQFloat sq_objtofloat(HSQOBJECT *o);
+SQUIRREL_API SQRESULT sq_getobjtypetag(HSQOBJECT *o,SQUserPointer * typetag);
+
+/*GC*/
+SQUIRREL_API SQInteger sq_collectgarbage(HSQUIRRELVM v);
+
+/*serialization*/
+SQUIRREL_API SQRESULT sq_writeclosure(HSQUIRRELVM vm,SQWRITEFUNC writef,SQUserPointer up);
+SQUIRREL_API SQRESULT sq_readclosure(HSQUIRRELVM vm,SQREADFUNC readf,SQUserPointer up);
+
+/*mem allocation*/
+SQUIRREL_API void *sq_malloc(SQUnsignedInteger size);
+SQUIRREL_API void *sq_realloc(void* p,SQUnsignedInteger oldsize,SQUnsignedInteger newsize);
+SQUIRREL_API void sq_free(void *p,SQUnsignedInteger size);
+
+/*debug*/
+SQUIRREL_API SQRESULT sq_stackinfos(HSQUIRRELVM v,SQInteger level,SQStackInfos *si);
+SQUIRREL_API void sq_setdebughook(HSQUIRRELVM v);
+
+/*UTILITY MACRO*/
+#define sq_isnumeric(o) ((o)._type&SQOBJECT_NUMERIC)
+#define sq_istable(o) ((o)._type==OT_TABLE)
+#define sq_isarray(o) ((o)._type==OT_ARRAY)
+#define sq_isfunction(o) ((o)._type==OT_FUNCPROTO)
+#define sq_isclosure(o) ((o)._type==OT_CLOSURE)
+#define sq_isgenerator(o) ((o)._type==OT_GENERATOR)
+#define sq_isnativeclosure(o) ((o)._type==OT_NATIVECLOSURE)
+#define sq_isstring(o) ((o)._type==OT_STRING)
+#define sq_isinteger(o) ((o)._type==OT_INTEGER)
+#define sq_isfloat(o) ((o)._type==OT_FLOAT)
+#define sq_isuserpointer(o) ((o)._type==OT_USERPOINTER)
+#define sq_isuserdata(o) ((o)._type==OT_USERDATA)
+#define sq_isthread(o) ((o)._type==OT_THREAD)
+#define sq_isnull(o) ((o)._type==OT_NULL)
+#define sq_isclass(o) ((o)._type==OT_CLASS)
+#define sq_isinstance(o) ((o)._type==OT_INSTANCE)
+#define sq_isbool(o) ((o)._type==OT_BOOL)
+#define sq_isweakref(o) ((o)._type==OT_WEAKREF)
+#define sq_type(o) ((o)._type)
+
+/* deprecated */
+#define sq_createslot(v,n) sq_newslot(v,n,SQFalse)
+
+#define SQ_OK (0)
+#define SQ_ERROR (-1)
+
+#define SQ_FAILED(res) (res<0)
+#define SQ_SUCCEEDED(res) (res>=0)
+
+#ifdef __cplusplus
+} /*extern "C"*/
+#endif
+
+#endif /*_SQUIRREL_H_*/
--- /dev/null
+static const SQChar serialize_state_nut[] = {
+0x74, 0x72, 0x79, 0x20, 0x7b, 0x0d, 0x0a, 0x09, 0x0d, 0x0a, 0x6c, 0x6f,
+0x63, 0x61, 0x6c, 0x20, 0x6f, 0x62, 0x6a, 0x73, 0x5f, 0x72, 0x65, 0x67,
+0x3d, 0x7b, 0x6d, 0x61, 0x78, 0x69, 0x64, 0x3d, 0x30, 0x2c, 0x72, 0x65,
+0x66, 0x73, 0x3d, 0x7b, 0x7d, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x63, 0x6f,
+0x6d, 0x70, 0x6c, 0x65, 0x78, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x20,
+0x3c, 0x2d, 0x20, 0x7b, 0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x74, 0x61, 0x62,
+0x6c, 0x65, 0x22, 0x5d, 0x20, 0x3d, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x2c,
+0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x61, 0x72, 0x72, 0x61, 0x79, 0x22, 0x5d,
+0x20, 0x3d, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x0d, 0x0a, 0x09, 0x5b,
+0x22, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x22, 0x5d, 0x20, 0x3d, 0x20, 0x6e,
+0x75, 0x6c, 0x6c, 0x2c, 0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x69, 0x6e, 0x73,
+0x74, 0x61, 0x6e, 0x63, 0x65, 0x22, 0x5d, 0x20, 0x3d, 0x20, 0x6e, 0x75,
+0x6c, 0x6c, 0x2c, 0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x77, 0x65, 0x61, 0x6b,
+0x72, 0x65, 0x66, 0x22, 0x5d, 0x20, 0x3d, 0x20, 0x6e, 0x75, 0x6c, 0x6c,
+0x2c, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x66, 0x75, 0x6e, 0x63,
+0x74, 0x69, 0x6f, 0x6e, 0x20, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x72,
+0x65, 0x66, 0x73, 0x28, 0x74, 0x29, 0x3a, 0x28, 0x6f, 0x62, 0x6a, 0x73,
+0x5f, 0x72, 0x65, 0x67, 0x29, 0x0d, 0x0a, 0x7b, 0x0d, 0x0a, 0x09, 0x69,
+0x66, 0x28, 0x74, 0x20, 0x3d, 0x3d, 0x20, 0x3a, 0x3a, 0x67, 0x65, 0x74,
+0x72, 0x6f, 0x6f, 0x74, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x29, 0x29,
+0x0d, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3b, 0x0d,
+0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6f, 0x74, 0x79, 0x70,
+0x65, 0x20, 0x3d, 0x20, 0x3a, 0x3a, 0x74, 0x79, 0x70, 0x65, 0x28, 0x74,
+0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x69, 0x66, 0x28, 0x6f, 0x74, 0x79, 0x70,
+0x65, 0x20, 0x69, 0x6e, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x78,
+0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x29, 0x0d, 0x0a, 0x09, 0x7b, 0x0d,
+0x0a, 0x09, 0x09, 0x69, 0x66, 0x28, 0x21, 0x28, 0x74, 0x20, 0x69, 0x6e,
+0x20, 0x6f, 0x62, 0x6a, 0x73, 0x5f, 0x72, 0x65, 0x67, 0x2e, 0x72, 0x65,
+0x66, 0x73, 0x29, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x6f,
+0x62, 0x6a, 0x73, 0x5f, 0x72, 0x65, 0x67, 0x2e, 0x72, 0x65, 0x66, 0x73,
+0x5b, 0x74, 0x5d, 0x20, 0x3c, 0x2d, 0x20, 0x6f, 0x62, 0x6a, 0x73, 0x5f,
+0x72, 0x65, 0x67, 0x2e, 0x6d, 0x61, 0x78, 0x69, 0x64, 0x2b, 0x2b, 0x3b,
+0x0d, 0x0a, 0x09, 0x09, 0x0d, 0x0a, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20,
+0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x65, 0x6f, 0x62, 0x6a, 0x65, 0x63,
+0x74, 0x28, 0x74, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
+0x28, 0x6f, 0x2c, 0x69, 0x2c, 0x76, 0x61, 0x6c, 0x29, 0x3a, 0x28, 0x6f,
+0x62, 0x6a, 0x73, 0x5f, 0x72, 0x65, 0x67, 0x29, 0x0d, 0x0a, 0x09, 0x09,
+0x20, 0x20, 0x20, 0x20, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x20, 0x20,
+0x20, 0x20, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x72, 0x65, 0x66, 0x73,
+0x28, 0x76, 0x61, 0x6c, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x20,
+0x20, 0x20, 0x20, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x72, 0x65, 0x66,
+0x73, 0x28, 0x69, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x20, 0x20, 0x20,
+0x20, 0x7d, 0x29, 0x0d, 0x0a, 0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x09,
+0x0d, 0x0a, 0x09, 0x7d, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x66,
+0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x67, 0x65, 0x74, 0x76,
+0x61, 0x6c, 0x75, 0x65, 0x28, 0x76, 0x29, 0x3a, 0x28, 0x6f, 0x62, 0x6a,
+0x73, 0x5f, 0x72, 0x65, 0x67, 0x29, 0x0d, 0x0a, 0x7b, 0x0d, 0x0a, 0x09,
+0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x28, 0x3a, 0x3a, 0x74, 0x79, 0x70,
+0x65, 0x28, 0x76, 0x29, 0x29, 0x0d, 0x0a, 0x09, 0x7b, 0x0d, 0x0a, 0x09,
+0x09, 0x63, 0x61, 0x73, 0x65, 0x20, 0x22, 0x74, 0x61, 0x62, 0x6c, 0x65,
+0x22, 0x3a, 0x0d, 0x0a, 0x09, 0x09, 0x63, 0x61, 0x73, 0x65, 0x20, 0x22,
+0x61, 0x72, 0x72, 0x61, 0x79, 0x22, 0x3a, 0x0d, 0x0a, 0x09, 0x09, 0x63,
+0x61, 0x73, 0x65, 0x20, 0x22, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x22, 0x3a,
+0x0d, 0x0a, 0x09, 0x09, 0x63, 0x61, 0x73, 0x65, 0x20, 0x22, 0x69, 0x6e,
+0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x22, 0x3a, 0x0d, 0x0a, 0x09, 0x09,
+0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x62, 0x6a, 0x73,
+0x5f, 0x72, 0x65, 0x67, 0x2e, 0x72, 0x65, 0x66, 0x73, 0x5b, 0x76, 0x5d,
+0x2e, 0x74, 0x6f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x29, 0x3b,
+0x0d, 0x0a, 0x09, 0x09, 0x63, 0x61, 0x73, 0x65, 0x20, 0x22, 0x69, 0x6e,
+0x74, 0x65, 0x67, 0x65, 0x72, 0x22, 0x3a, 0x0d, 0x0a, 0x09, 0x09, 0x63,
+0x61, 0x73, 0x65, 0x20, 0x22, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x22, 0x3a,
+0x0d, 0x0a, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75,
+0x72, 0x6e, 0x20, 0x76, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x63, 0x61, 0x73,
+0x65, 0x20, 0x22, 0x62, 0x6f, 0x6f, 0x6c, 0x22, 0x3a, 0x0d, 0x0a, 0x09,
+0x09, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20,
+0x76, 0x2e, 0x74, 0x6f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x29,
+0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x63, 0x61, 0x73, 0x65, 0x20, 0x22, 0x73,
+0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x3a, 0x0d, 0x0a, 0x09, 0x09, 0x09,
+0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, 0x3b, 0x0d, 0x0a, 0x09,
+0x09, 0x63, 0x61, 0x73, 0x65, 0x20, 0x22, 0x6e, 0x75, 0x6c, 0x6c, 0x22,
+0x3a, 0x0d, 0x0a, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74,
+0x75, 0x72, 0x6e, 0x20, 0x22, 0x6e, 0x75, 0x6c, 0x6c, 0x22, 0x3b, 0x0d,
+0x0a, 0x09, 0x09, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x0d,
+0x0a, 0x09, 0x09, 0x09, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x72, 0x65, 0x74,
+0x75, 0x72, 0x6e, 0x20, 0x70, 0x61, 0x63, 0x6b, 0x5f, 0x74, 0x79, 0x70,
+0x65, 0x28, 0x3a, 0x3a, 0x74, 0x79, 0x70, 0x65, 0x28, 0x76, 0x29, 0x29,
+0x3b, 0x0d, 0x0a, 0x09, 0x7d, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a,
+0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x64,
+0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x3d, 0x7b, 0x0d, 0x0a, 0x09, 0x5b,
+0x22, 0x6e, 0x75, 0x6c, 0x6c, 0x22, 0x5d, 0x3d, 0x22, 0x6e, 0x22, 0x2c,
+0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22,
+0x5d, 0x3d, 0x22, 0x73, 0x22, 0x2c, 0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x69,
+0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x22, 0x5d, 0x3d, 0x22, 0x69, 0x22,
+0x2c, 0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x22,
+0x5d, 0x3d, 0x22, 0x66, 0x22, 0x2c, 0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x75,
+0x73, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x22, 0x5d, 0x3d, 0x22, 0x75,
+0x22, 0x2c, 0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x66, 0x75, 0x6e, 0x63, 0x74,
+0x69, 0x6f, 0x6e, 0x22, 0x5d, 0x3d, 0x22, 0x66, 0x6e, 0x22, 0x2c, 0x0d,
+0x0a, 0x09, 0x5b, 0x22, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x5d, 0x3d,
+0x22, 0x74, 0x22, 0x2c, 0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x61, 0x72, 0x72,
+0x61, 0x79, 0x22, 0x5d, 0x3d, 0x22, 0x61, 0x22, 0x2c, 0x0d, 0x0a, 0x09,
+0x5b, 0x22, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x22,
+0x5d, 0x3d, 0x22, 0x67, 0x22, 0x2c, 0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x74,
+0x68, 0x72, 0x65, 0x61, 0x64, 0x22, 0x5d, 0x3d, 0x22, 0x68, 0x22, 0x2c,
+0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63,
+0x65, 0x22, 0x5d, 0x3d, 0x22, 0x78, 0x22, 0x2c, 0x20, 0x0d, 0x0a, 0x09,
+0x5b, 0x22, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x22, 0x5d, 0x3d, 0x22, 0x79,
+0x22, 0x2c, 0x20, 0x20, 0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x62, 0x6f, 0x6f,
+0x6c, 0x22, 0x5d, 0x3d, 0x22, 0x62, 0x22, 0x2c, 0x0d, 0x0a, 0x09, 0x5b,
+0x22, 0x77, 0x65, 0x61, 0x6b, 0x72, 0x65, 0x66, 0x22, 0x5d, 0x3d, 0x22,
+0x77, 0x22, 0x20, 0x20, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x66,
+0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x63, 0x6b,
+0x5f, 0x74, 0x79, 0x70, 0x65, 0x28, 0x74, 0x79, 0x70, 0x65, 0x29, 0x3a,
+0x28, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x5f, 0x74, 0x79, 0x70, 0x65,
+0x73, 0x29, 0x0d, 0x0a, 0x7b, 0x0d, 0x0a, 0x09, 0x69, 0x66, 0x28, 0x74,
+0x79, 0x70, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x70, 0x61, 0x63, 0x6b, 0x65,
+0x64, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x29, 0x72, 0x65, 0x74, 0x75,
+0x72, 0x6e, 0x20, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x5f, 0x74, 0x79,
+0x70, 0x65, 0x73, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x5d, 0x0d, 0x0a, 0x09,
+0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x79, 0x70, 0x65, 0x0d,
+0x0a, 0x7d, 0x20, 0x0d, 0x0a, 0x0d, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74,
+0x69, 0x6f, 0x6e, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x65, 0x6f,
+0x62, 0x6a, 0x65, 0x63, 0x74, 0x28, 0x6f, 0x62, 0x6a, 0x2c, 0x66, 0x75,
+0x6e, 0x63, 0x29, 0x0d, 0x0a, 0x7b, 0x0d, 0x0a, 0x09, 0x6c, 0x6f, 0x63,
+0x61, 0x6c, 0x20, 0x74, 0x79, 0x20, 0x3d, 0x20, 0x3a, 0x3a, 0x74, 0x79,
+0x70, 0x65, 0x28, 0x6f, 0x62, 0x6a, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x69,
+0x66, 0x28, 0x74, 0x79, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x69, 0x6e, 0x73,
+0x74, 0x61, 0x6e, 0x63, 0x65, 0x22, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x09,
+0x09, 0x74, 0x72, 0x79, 0x20, 0x7b, 0x20, 0x2f, 0x2f, 0x54, 0x52, 0x59,
+0x20, 0x54, 0x4f, 0x20, 0x55, 0x53, 0x45, 0x20, 0x5f, 0x6e, 0x65, 0x78,
+0x74, 0x69, 0x0d, 0x0a, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6f,
+0x72, 0x65, 0x61, 0x63, 0x68, 0x28, 0x69, 0x64, 0x78, 0x2c, 0x76, 0x61,
+0x6c, 0x20, 0x69, 0x6e, 0x20, 0x6f, 0x62, 0x6a, 0x29, 0x0d, 0x0a, 0x09,
+0x09, 0x20, 0x20, 0x20, 0x20, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09,
+0x66, 0x75, 0x6e, 0x63, 0x28, 0x6f, 0x62, 0x6a, 0x2c, 0x69, 0x64, 0x78,
+0x2c, 0x76, 0x61, 0x6c, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x20, 0x20,
+0x20, 0x20, 0x7d, 0x0d, 0x0a, 0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x09,
+0x63, 0x61, 0x74, 0x63, 0x68, 0x28, 0x65, 0x29, 0x20, 0x7b, 0x0d, 0x0a,
+0x09, 0x09, 0x20, 0x20, 0x20, 0x66, 0x6f, 0x72, 0x65, 0x61, 0x63, 0x68,
+0x28, 0x69, 0x64, 0x78, 0x2c, 0x76, 0x61, 0x6c, 0x20, 0x69, 0x6e, 0x20,
+0x6f, 0x62, 0x6a, 0x2e, 0x67, 0x65, 0x74, 0x63, 0x6c, 0x61, 0x73, 0x73,
+0x28, 0x29, 0x29, 0x0d, 0x0a, 0x09, 0x09, 0x20, 0x20, 0x20, 0x7b, 0x0d,
+0x0a, 0x09, 0x09, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x28, 0x6f, 0x62, 0x6a,
+0x2c, 0x69, 0x64, 0x78, 0x2c, 0x6f, 0x62, 0x6a, 0x5b, 0x69, 0x64, 0x78,
+0x5d, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x20, 0x20, 0x20, 0x7d, 0x0d,
+0x0a, 0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x65,
+0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x74, 0x79, 0x20, 0x3d, 0x3d,
+0x20, 0x22, 0x77, 0x65, 0x61, 0x6b, 0x72, 0x65, 0x66, 0x22, 0x29, 0x20,
+0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x28, 0x6f, 0x62,
+0x6a, 0x2c, 0x22, 0x40, 0x72, 0x65, 0x66, 0x22, 0x2c, 0x6f, 0x62, 0x6a,
+0x2e, 0x72, 0x65, 0x66, 0x28, 0x29, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x7d,
+0x0d, 0x0a, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, 0x0d, 0x0a, 0x09,
+0x09, 0x66, 0x6f, 0x72, 0x65, 0x61, 0x63, 0x68, 0x28, 0x69, 0x64, 0x78,
+0x2c, 0x76, 0x61, 0x6c, 0x20, 0x69, 0x6e, 0x20, 0x6f, 0x62, 0x6a, 0x29,
+0x0d, 0x0a, 0x09, 0x09, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x20, 0x20, 0x20,
+0x20, 0x66, 0x75, 0x6e, 0x63, 0x28, 0x6f, 0x62, 0x6a, 0x2c, 0x69, 0x64,
+0x78, 0x2c, 0x76, 0x61, 0x6c, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x7d,
+0x0d, 0x0a, 0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x0d, 0x0a, 0x7d,
+0x0d, 0x0a, 0x0d, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
+0x20, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x74, 0x72, 0x65, 0x65, 0x28,
+0x29, 0x3a, 0x28, 0x6f, 0x62, 0x6a, 0x73, 0x5f, 0x72, 0x65, 0x67, 0x29,
+0x0d, 0x0a, 0x7b, 0x0d, 0x0a, 0x09, 0x66, 0x6f, 0x72, 0x65, 0x61, 0x63,
+0x68, 0x28, 0x69, 0x2c, 0x6f, 0x20, 0x69, 0x6e, 0x20, 0x6f, 0x62, 0x6a,
+0x73, 0x5f, 0x72, 0x65, 0x67, 0x2e, 0x72, 0x65, 0x66, 0x73, 0x29, 0x0d,
+0x0a, 0x09, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x62, 0x65, 0x67, 0x69, 0x6e,
+0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x28, 0x22, 0x6f, 0x22, 0x29,
+0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75,
+0x74, 0x65, 0x28, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x2c, 0x28, 0x69,
+0x3d, 0x3d, 0x3a, 0x3a, 0x67, 0x65, 0x74, 0x72, 0x6f, 0x6f, 0x74, 0x74,
+0x61, 0x62, 0x6c, 0x65, 0x28, 0x29, 0x3f, 0x22, 0x72, 0x22, 0x3a, 0x70,
+0x61, 0x63, 0x6b, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x28, 0x3a, 0x3a, 0x74,
+0x79, 0x70, 0x65, 0x28, 0x69, 0x29, 0x29, 0x29, 0x29, 0x3b, 0x0d, 0x0a,
+0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x5f, 0x74, 0x79, 0x70,
+0x65, 0x6f, 0x66, 0x20, 0x3d, 0x20, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66,
+0x20, 0x69, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x28, 0x5f, 0x74,
+0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x21, 0x3d, 0x20, 0x3a, 0x3a, 0x74,
+0x79, 0x70, 0x65, 0x28, 0x69, 0x29, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x09,
+0x09, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28,
+0x22, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x22, 0x2c, 0x5f, 0x74, 0x79,
+0x70, 0x65, 0x6f, 0x66, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x7d, 0x0d,
+0x0a, 0x09, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65,
+0x28, 0x22, 0x72, 0x65, 0x66, 0x22, 0x2c, 0x6f, 0x2e, 0x74, 0x6f, 0x73,
+0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x29, 0x29, 0x3b, 0x0d, 0x0a, 0x09,
+0x09, 0x69, 0x66, 0x28, 0x69, 0x20, 0x21, 0x3d, 0x20, 0x3a, 0x3a, 0x67,
+0x65, 0x74, 0x72, 0x6f, 0x6f, 0x74, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x28,
+0x29, 0x29, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x69, 0x74, 0x65, 0x72,
+0x61, 0x74, 0x65, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x28, 0x69, 0x2c,
+0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x6f, 0x62,
+0x6a, 0x2c, 0x69, 0x64, 0x78, 0x2c, 0x76, 0x61, 0x6c, 0x29, 0x20, 0x7b,
+0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x28, 0x3a, 0x3a, 0x74,
+0x79, 0x70, 0x65, 0x28, 0x76, 0x61, 0x6c, 0x29, 0x20, 0x3d, 0x3d, 0x20,
+0x22, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x29, 0x0d,
+0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e,
+0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0d, 0x0a, 0x09, 0x09,
+0x09, 0x09, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x65, 0x6c, 0x65, 0x6d, 0x65,
+0x6e, 0x74, 0x28, 0x22, 0x65, 0x22, 0x29, 0x3b, 0x09, 0x0d, 0x0a, 0x09,
+0x09, 0x09, 0x09, 0x09, 0x65, 0x6d, 0x69, 0x74, 0x76, 0x61, 0x6c, 0x75,
+0x65, 0x28, 0x22, 0x6b, 0x74, 0x22, 0x2c, 0x22, 0x6b, 0x76, 0x22, 0x2c,
+0x69, 0x64, 0x78, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09,
+0x65, 0x6d, 0x69, 0x74, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x28, 0x22, 0x76,
+0x74, 0x22, 0x2c, 0x22, 0x76, 0x22, 0x2c, 0x6f, 0x62, 0x6a, 0x5b, 0x69,
+0x64, 0x78, 0x5d, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x65,
+0x6e, 0x64, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x28, 0x22, 0x65,
+0x22, 0x29, 0x3b, 0x09, 0x0d, 0x0a, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x7d,
+0x29, 0x0d, 0x0a, 0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x09, 0x65, 0x6e,
+0x64, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x28, 0x22, 0x6f, 0x22,
+0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x7d, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d,
+0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x76,
+0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x5f, 0x77, 0x61, 0x74, 0x63, 0x68,
+0x28, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x73, 0x2c, 0x69, 0x64, 0x2c, 0x65,
+0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x29, 0x0d, 0x0a,
+0x7b, 0x0d, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75,
+0x6e, 0x63, 0x5f, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x72, 0x65, 0x74, 0x75,
+0x72, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20,
+0x28, 0x22, 0x0d, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70,
+0x61, 0x72, 0x61, 0x6d, 0x73, 0x3d, 0x5b, 0x5d, 0x3b, 0x0d, 0x0a, 0x09,
+0x0d, 0x0a, 0x09, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x2e, 0x61, 0x70,
+0x70, 0x65, 0x6e, 0x64, 0x28, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x73, 0x5b,
+0x22, 0x74, 0x68, 0x69, 0x73, 0x22, 0x5d, 0x29, 0x0d, 0x0a, 0x09, 0x6c,
+0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x3d, 0x31,
+0x3b, 0x0d, 0x0a, 0x09, 0x66, 0x6f, 0x72, 0x65, 0x61, 0x63, 0x68, 0x28,
+0x69, 0x2c, 0x76, 0x20, 0x69, 0x6e, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c,
+0x73, 0x29, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x28, 0x69, 0x21,
+0x3d, 0x22, 0x74, 0x68, 0x69, 0x73, 0x22, 0x20, 0x26, 0x26, 0x20, 0x69,
+0x5b, 0x30, 0x5d, 0x20, 0x21, 0x3d, 0x20, 0x27, 0x40, 0x27, 0x29, 0x7b,
+0x20, 0x2f, 0x2f, 0x66, 0x6f, 0x72, 0x65, 0x61, 0x63, 0x68, 0x20, 0x69,
+0x74, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x20, 0x73, 0x74, 0x61,
+0x72, 0x74, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x40, 0x0d, 0x0a, 0x09,
+0x09, 0x09, 0x69, 0x66, 0x28, 0x21, 0x66, 0x69, 0x72, 0x73, 0x74, 0x29,
+0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x5f,
+0x73, 0x72, 0x63, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x5f, 0x73, 0x72, 0x63,
+0x2b, 0x22, 0x2c, 0x22, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x0d, 0x0a,
+0x09, 0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x66, 0x69, 0x72,
+0x73, 0x74, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x0d, 0x0a, 0x09, 0x09, 0x09,
+0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e,
+0x64, 0x28, 0x76, 0x29, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x66, 0x75, 0x6e,
+0x63, 0x5f, 0x73, 0x72, 0x63, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x5f, 0x73,
+0x72, 0x63, 0x2b, 0x69, 0x0d, 0x0a, 0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09,
+0x7d, 0x0d, 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x5f, 0x73, 0x72, 0x63,
+0x3d, 0x66, 0x75, 0x6e, 0x63, 0x5f, 0x73, 0x72, 0x63, 0x2b, 0x22, 0x29,
+0x7b, 0x5c, 0x6e, 0x22, 0x0d, 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x5f,
+0x73, 0x72, 0x63, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x5f, 0x73, 0x72, 0x63,
+0x2b, 0x22, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x28, 0x22, 0x2b,
+0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2b, 0x22,
+0x29, 0x5c, 0x6e, 0x7d, 0x22, 0x0d, 0x0a, 0x09, 0x0d, 0x0a, 0x09, 0x74,
+0x72, 0x79, 0x20, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61,
+0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x3d, 0x3a, 0x3a, 0x63, 0x6f, 0x6d,
+0x70, 0x69, 0x6c, 0x65, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x66,
+0x75, 0x6e, 0x63, 0x5f, 0x73, 0x72, 0x63, 0x29, 0x3b, 0x0d, 0x0a, 0x09,
+0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x7b, 0x73, 0x74, 0x61,
+0x74, 0x75, 0x73, 0x3d, 0x22, 0x6f, 0x6b, 0x22, 0x20, 0x2c, 0x20, 0x76,
+0x61, 0x6c, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x28, 0x29, 0x2e, 0x61, 0x63,
+0x61, 0x6c, 0x6c, 0x28, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x29, 0x7d,
+0x3b, 0x0d, 0x0a, 0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x63, 0x61, 0x74, 0x63,
+0x68, 0x28, 0x65, 0x29, 0x0d, 0x0a, 0x09, 0x7b, 0x0d, 0x0a, 0x09, 0x09,
+0x0d, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x7b,
+0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3d, 0x22, 0x65, 0x72, 0x72, 0x6f,
+0x72, 0x22, 0x7d, 0x0d, 0x0a, 0x09, 0x7d, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a,
+0x0d, 0x0a, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
+0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
+0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
+0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
+0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
+0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
+0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x0d, 0x0a, 0x2f, 0x2f, 0x2f,
+0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
+0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
+0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
+0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
+0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
+0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
+0x2f, 0x2f, 0x0d, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
+0x20, 0x65, 0x6d, 0x69, 0x74, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x28, 0x74,
+0x79, 0x70, 0x65, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x2c, 0x76,
+0x61, 0x6c, 0x75, 0x65, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x2c,
+0x76, 0x61, 0x6c, 0x29, 0x0d, 0x0a, 0x7b, 0x0d, 0x0a, 0x09, 0x61, 0x74,
+0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x74, 0x79, 0x70, 0x65,
+0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x2c, 0x70, 0x61, 0x63, 0x6b,
+0x5f, 0x74, 0x79, 0x70, 0x65, 0x28, 0x3a, 0x3a, 0x74, 0x79, 0x70, 0x65,
+0x28, 0x76, 0x61, 0x6c, 0x29, 0x29, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x61,
+0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x76, 0x61, 0x6c,
+0x75, 0x65, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x2c, 0x67, 0x65,
+0x74, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x28, 0x76, 0x61, 0x6c, 0x29, 0x2e,
+0x74, 0x6f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x29, 0x29, 0x3b,
+0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c,
+0x20, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x3d, 0x5b, 0x5d, 0x0d, 0x0a, 0x6c,
+0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x3d, 0x33,
+0x3b, 0x0d, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x73, 0x69, 0x3b,
+0x0d, 0x0a, 0x0d, 0x0a, 0x2f, 0x2f, 0x74, 0x72, 0x79, 0x20, 0x7b, 0x0d,
+0x0a, 0x09, 0x2f, 0x2f, 0x45, 0x4e, 0x55, 0x4d, 0x45, 0x52, 0x41, 0x54,
+0x45, 0x20, 0x54, 0x48, 0x45, 0x20, 0x53, 0x54, 0x41, 0x43, 0x4b, 0x20,
+0x57, 0x41, 0x54, 0x43, 0x48, 0x45, 0x53, 0x0d, 0x0a, 0x09, 0x77, 0x68,
+0x69, 0x6c, 0x65, 0x28, 0x73, 0x69, 0x3d, 0x3a, 0x3a, 0x67, 0x65, 0x74,
+0x73, 0x74, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x66, 0x6f, 0x73, 0x28, 0x6c,
+0x65, 0x76, 0x65, 0x6c, 0x29, 0x29, 0x0d, 0x0a, 0x09, 0x7b, 0x0d, 0x0a,
+0x09, 0x09, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x61, 0x70, 0x70, 0x65,
+0x6e, 0x64, 0x28, 0x73, 0x69, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x6c,
+0x65, 0x76, 0x65, 0x6c, 0x2b, 0x2b, 0x3b, 0x0d, 0x0a, 0x09, 0x7d, 0x0d,
+0x0a, 0x0d, 0x0a, 0x09, 0x2f, 0x2f, 0x45, 0x56, 0x41, 0x4c, 0x55, 0x41,
+0x54, 0x45, 0x20, 0x41, 0x4c, 0x4c, 0x20, 0x57, 0x41, 0x54, 0x43, 0x48,
+0x45, 0x53, 0x0d, 0x0a, 0x09, 0x6f, 0x62, 0x6a, 0x73, 0x5f, 0x72, 0x65,
+0x67, 0x2e, 0x72, 0x65, 0x66, 0x73, 0x5b, 0x3a, 0x3a, 0x67, 0x65, 0x74,
+0x72, 0x6f, 0x6f, 0x74, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x29, 0x5d,
+0x20, 0x3c, 0x2d, 0x20, 0x6f, 0x62, 0x6a, 0x73, 0x5f, 0x72, 0x65, 0x67,
+0x2e, 0x6d, 0x61, 0x78, 0x69, 0x64, 0x2b, 0x2b, 0x3b, 0x0d, 0x0a, 0x09,
+0x66, 0x6f, 0x72, 0x65, 0x61, 0x63, 0x68, 0x28, 0x69, 0x2c, 0x76, 0x61,
+0x6c, 0x20, 0x69, 0x6e, 0x20, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x29, 0x0d,
+0x0a, 0x09, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x28, 0x76, 0x61,
+0x6c, 0x2e, 0x73, 0x72, 0x63, 0x21, 0x3d, 0x22, 0x4e, 0x41, 0x54, 0x49,
+0x56, 0x45, 0x22, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x69,
+0x66, 0x28, 0x22, 0x77, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x22, 0x20,
+0x69, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x29, 0x20, 0x7b, 0x0d, 0x0a,
+0x09, 0x09, 0x09, 0x09, 0x76, 0x61, 0x6c, 0x2e, 0x77, 0x61, 0x74, 0x63,
+0x68, 0x65, 0x73, 0x20, 0x3c, 0x2d, 0x20, 0x7b, 0x7d, 0x0d, 0x0a, 0x09,
+0x09, 0x09, 0x09, 0x66, 0x6f, 0x72, 0x65, 0x61, 0x63, 0x68, 0x28, 0x69,
+0x2c, 0x77, 0x61, 0x74, 0x63, 0x68, 0x20, 0x69, 0x6e, 0x20, 0x77, 0x61,
+0x74, 0x63, 0x68, 0x65, 0x73, 0x29, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09,
+0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x28, 0x76,
+0x61, 0x6c, 0x2e, 0x73, 0x72, 0x63, 0x21, 0x3d, 0x22, 0x4e, 0x41, 0x54,
+0x49, 0x56, 0x45, 0x22, 0x29, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09,
+0x09, 0x09, 0x76, 0x61, 0x6c, 0x2e, 0x77, 0x61, 0x74, 0x63, 0x68, 0x65,
+0x73, 0x5b, 0x69, 0x5d, 0x20, 0x3c, 0x2d, 0x20, 0x65, 0x76, 0x61, 0x6c,
+0x75, 0x61, 0x74, 0x65, 0x5f, 0x77, 0x61, 0x74, 0x63, 0x68, 0x28, 0x76,
+0x61, 0x6c, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x73, 0x2c, 0x69, 0x2c,
+0x77, 0x61, 0x74, 0x63, 0x68, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09,
+0x09, 0x09, 0x09, 0x69, 0x66, 0x28, 0x76, 0x61, 0x6c, 0x2e, 0x77, 0x61,
+0x74, 0x63, 0x68, 0x65, 0x73, 0x5b, 0x69, 0x5d, 0x2e, 0x73, 0x74, 0x61,
+0x74, 0x75, 0x73, 0x21, 0x3d, 0x22, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22,
+0x29, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x62, 0x75,
+0x69, 0x6c, 0x64, 0x5f, 0x72, 0x65, 0x66, 0x73, 0x28, 0x76, 0x61, 0x6c,
+0x2e, 0x77, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x5b, 0x69, 0x5d, 0x2e,
+0x76, 0x61, 0x6c, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09,
+0x7d, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x65, 0x6c, 0x73, 0x65,
+0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x76, 0x61, 0x6c,
+0x2e, 0x77, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x5b, 0x69, 0x5d, 0x20,
+0x3c, 0x2d, 0x20, 0x7b, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3d, 0x22,
+0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x7d, 0x0d, 0x0a, 0x09, 0x09, 0x09,
+0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x76, 0x61,
+0x6c, 0x2e, 0x77, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x5b, 0x69, 0x5d,
+0x2e, 0x65, 0x78, 0x70, 0x20, 0x3c, 0x2d, 0x20, 0x77, 0x61, 0x74, 0x63,
+0x68, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09,
+0x09, 0x09, 0x09, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09,
+0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x09, 0x66, 0x6f, 0x72, 0x65, 0x61, 0x63,
+0x68, 0x28, 0x69, 0x2c, 0x6c, 0x20, 0x69, 0x6e, 0x20, 0x76, 0x61, 0x6c,
+0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x73, 0x29, 0x0d, 0x0a, 0x09, 0x09,
+0x09, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x72, 0x65, 0x66, 0x73, 0x28,
+0x6c, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x0d,
+0x0a, 0x09, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x65, 0x6c, 0x65, 0x6d, 0x65,
+0x6e, 0x74, 0x28, 0x22, 0x6f, 0x62, 0x6a, 0x73, 0x22, 0x29, 0x3b, 0x0d,
+0x0a, 0x09, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x74, 0x72, 0x65, 0x65,
+0x28, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x65, 0x6c, 0x65,
+0x6d, 0x65, 0x6e, 0x74, 0x28, 0x22, 0x6f, 0x62, 0x6a, 0x73, 0x22, 0x29,
+0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x09, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x65,
+0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x28, 0x22, 0x63, 0x61, 0x6c, 0x6c,
+0x73, 0x22, 0x29, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x09, 0x66, 0x6f, 0x72,
+0x65, 0x61, 0x63, 0x68, 0x28, 0x69, 0x2c, 0x76, 0x61, 0x6c, 0x20, 0x69,
+0x6e, 0x20, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x29, 0x0d, 0x0a, 0x09, 0x7b,
+0x0d, 0x0a, 0x0d, 0x0a, 0x09, 0x09, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x65,
+0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x28, 0x22, 0x63, 0x61, 0x6c, 0x6c,
+0x22, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69,
+0x62, 0x75, 0x74, 0x65, 0x28, 0x22, 0x66, 0x6e, 0x63, 0x22, 0x2c, 0x76,
+0x61, 0x6c, 0x2e, 0x66, 0x75, 0x6e, 0x63, 0x29, 0x3b, 0x0d, 0x0a, 0x09,
+0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x22,
+0x73, 0x72, 0x63, 0x22, 0x2c, 0x76, 0x61, 0x6c, 0x2e, 0x73, 0x72, 0x63,
+0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62,
+0x75, 0x74, 0x65, 0x28, 0x22, 0x6c, 0x69, 0x6e, 0x65, 0x22, 0x2c, 0x76,
+0x61, 0x6c, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x74, 0x6f, 0x73, 0x74,
+0x72, 0x69, 0x6e, 0x67, 0x28, 0x29, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09,
+0x66, 0x6f, 0x72, 0x65, 0x61, 0x63, 0x68, 0x28, 0x69, 0x2c, 0x76, 0x20,
+0x69, 0x6e, 0x20, 0x76, 0x61, 0x6c, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c,
+0x73, 0x29, 0x0d, 0x0a, 0x09, 0x09, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09,
+0x62, 0x65, 0x67, 0x69, 0x6e, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74,
+0x28, 0x22, 0x6c, 0x22, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09,
+0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x22, 0x6e,
+0x61, 0x6d, 0x65, 0x22, 0x2c, 0x67, 0x65, 0x74, 0x76, 0x61, 0x6c, 0x75,
+0x65, 0x28, 0x69, 0x29, 0x2e, 0x74, 0x6f, 0x73, 0x74, 0x72, 0x69, 0x6e,
+0x67, 0x28, 0x29, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x65,
+0x6d, 0x69, 0x74, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x28, 0x22, 0x74, 0x79,
+0x70, 0x65, 0x22, 0x2c, 0x22, 0x76, 0x61, 0x6c, 0x22, 0x2c, 0x76, 0x29,
+0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x65, 0x6c, 0x65,
+0x6d, 0x65, 0x6e, 0x74, 0x28, 0x22, 0x6c, 0x22, 0x29, 0x3b, 0x0d, 0x0a,
+0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x28, 0x22, 0x77,
+0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x22, 0x20, 0x69, 0x6e, 0x20, 0x76,
+0x61, 0x6c, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x66, 0x6f,
+0x72, 0x65, 0x61, 0x63, 0x68, 0x28, 0x69, 0x2c, 0x76, 0x20, 0x69, 0x6e,
+0x20, 0x76, 0x61, 0x6c, 0x2e, 0x77, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73,
+0x29, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09,
+0x09, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e,
+0x74, 0x28, 0x22, 0x77, 0x22, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09,
+0x09, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28,
+0x22, 0x69, 0x64, 0x22, 0x2c, 0x69, 0x2e, 0x74, 0x6f, 0x73, 0x74, 0x72,
+0x69, 0x6e, 0x67, 0x28, 0x29, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09,
+0x09, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28,
+0x22, 0x65, 0x78, 0x70, 0x22, 0x2c, 0x76, 0x2e, 0x65, 0x78, 0x70, 0x29,
+0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x61, 0x74, 0x74, 0x72,
+0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x22, 0x73, 0x74, 0x61, 0x74, 0x75,
+0x73, 0x22, 0x2c, 0x76, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x29,
+0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x28, 0x76,
+0x2e, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x21, 0x3d, 0x22, 0x65, 0x72,
+0x72, 0x6f, 0x72, 0x22, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09,
+0x09, 0x09, 0x09, 0x65, 0x6d, 0x69, 0x74, 0x76, 0x61, 0x6c, 0x75, 0x65,
+0x28, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x2c, 0x22, 0x76, 0x61, 0x6c,
+0x22, 0x2c, 0x76, 0x2e, 0x76, 0x61, 0x6c, 0x29, 0x3b, 0x0d, 0x0a, 0x09,
+0x09, 0x09, 0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x65,
+0x6e, 0x64, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x28, 0x22, 0x77,
+0x22, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09,
+0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x65, 0x6c, 0x65,
+0x6d, 0x65, 0x6e, 0x74, 0x28, 0x22, 0x63, 0x61, 0x6c, 0x6c, 0x22, 0x29,
+0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x20, 0x0d, 0x0a, 0x09, 0x7d, 0x0d, 0x0a,
+0x09, 0x65, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x28,
+0x22, 0x63, 0x61, 0x6c, 0x6c, 0x73, 0x22, 0x29, 0x3b, 0x0d, 0x0a, 0x0d,
+0x0a, 0x0d, 0x0a, 0x09, 0x6f, 0x62, 0x6a, 0x73, 0x5f, 0x72, 0x65, 0x67,
+0x20, 0x3d, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x3b, 0x0d, 0x0a, 0x09, 0x73,
+0x74, 0x61, 0x63, 0x6b, 0x20, 0x3d, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x3b,
+0x0d, 0x0a, 0x09, 0x0d, 0x0a, 0x09, 0x69, 0x66, 0x28, 0x22, 0x63, 0x6f,
+0x6c, 0x6c, 0x65, 0x63, 0x74, 0x67, 0x61, 0x72, 0x62, 0x61, 0x67, 0x65,
+0x22, 0x20, 0x69, 0x6e, 0x20, 0x3a, 0x3a, 0x67, 0x65, 0x74, 0x72, 0x6f,
+0x6f, 0x74, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x29, 0x29, 0x20, 0x3a,
+0x3a, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x67, 0x61, 0x72, 0x62,
+0x61, 0x67, 0x65, 0x28, 0x29, 0x3b, 0x0d, 0x0a, 0x7d, 0x63, 0x61, 0x74,
+0x63, 0x68, 0x28, 0x65, 0x29, 0x0d, 0x0a, 0x7b, 0x0d, 0x0a, 0x09, 0x3a,
+0x3a, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x22, 0x45, 0x52, 0x52, 0x4f,
+0x52, 0x22, 0x2b, 0x65, 0x2b, 0x22, 0x5c, 0x6e, 0x22, 0x29, 0x3b, 0x0d,
+0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x00,
+};
--- /dev/null
+#include <squirrel.h>
+#include <assert.h>
+#include <sqstdblob.h>
+#include "sqrdbg.h"
+#include "sqdbgserver.h"
+
+
+#ifndef _UNICODE
+#define scstrcpy strcpy
+#else
+#define scstrcpy wcscpy
+#endif
+struct XMLEscape{
+ const SQChar c;
+ const SQChar *esc;
+};
+
+#define SQDBG_DEBUG_HOOK _SC("_sqdbg_debug_hook_")
+#define SQDBG_ERROR_HANDLER _SC("_sqdbg_error_handler_")
+
+XMLEscape g_escapes[]={
+ {_SC('<'),_SC("<")},{'>',_SC(">")},{_SC('&'),_SC("&")},{_SC('\''),_SC("'")},{_SC('\"'),_SC(""")},{_SC('\n'),_SC(""n")},{_SC('\r'),_SC(""r")},{0, NULL}
+};
+
+const SQChar *IntToString(int n)
+{
+ static SQChar temp[256];
+ scsprintf(temp,_SC("%d"),n);
+ return temp;
+}
+
+SQInteger debug_hook(HSQUIRRELVM v);
+SQInteger error_handler(HSQUIRRELVM v);
+
+SQInteger beginelement(HSQUIRRELVM v)
+{
+ SQUserPointer up;
+ const SQChar *name;
+ sq_getuserpointer(v,-1,&up);
+ SQDbgServer *self = (SQDbgServer*)up;
+ sq_getuserpointer(v,-1,&up);
+ sq_getstring(v,2,&name);
+ self->BeginElement(name);
+ return 0;
+}
+
+SQInteger endelement(HSQUIRRELVM v)
+{
+ SQUserPointer up;
+ const SQChar *name;
+ sq_getuserpointer(v,-1,&up);
+ SQDbgServer *self = (SQDbgServer*)up;
+ sq_getuserpointer(v,-1,&up);
+ sq_getstring(v,2,&name);
+ self->EndElement(name);
+ return 0;
+}
+
+SQInteger attribute(HSQUIRRELVM v)
+{
+ SQUserPointer up;
+ const SQChar *name,*value;
+ sq_getuserpointer(v,-1,&up);
+ SQDbgServer *self = (SQDbgServer*)up;
+ sq_getuserpointer(v,-1,&up);
+ sq_getstring(v,2,&name);
+ sq_getstring(v,3,&value);
+ self->Attribute(name,value);
+ return 0;
+}
+
+const SQChar *EscapeXMLString(HSQUIRRELVM v,const SQChar *s)
+{
+
+ SQChar *temp=sq_getscratchpad(v,((int)scstrlen(s)*6) + sizeof(SQChar));
+ SQChar *dest=temp;
+ while(*s!=_SC('\0')){
+ int i=0;
+ bool escaped=false;
+ while(g_escapes[i].esc!=NULL){
+ if(*s==g_escapes[i].c){
+ scstrcpy(dest,g_escapes[i].esc);
+ dest+=scstrlen(g_escapes[i].esc);
+ escaped=true;
+ break;
+ }
+ i++;
+ }
+ if(!escaped){*dest=*s;*dest++;}
+ *s++;
+ }
+ *dest=_SC('\0');
+ return temp;
+}
+
+SQDbgServer::SQDbgServer(HSQUIRRELVM v)
+{
+ _ready = false;
+ _nestedcalls = 0;
+ _autoupdate = false;
+ _v = v;
+ _state = eDBG_Running;
+ _accept = INVALID_SOCKET;
+ _endpoint = INVALID_SOCKET;
+ _maxrecursion = 10;
+ sq_resetobject(&_debugroot);
+}
+
+SQDbgServer::~SQDbgServer()
+{
+ sq_release(_v,&_debugroot);
+ if(_accept != INVALID_SOCKET)
+ sqdbg_closesocket(_accept);
+ if(_endpoint != INVALID_SOCKET)
+ sqdbg_closesocket(_endpoint);
+}
+
+bool SQDbgServer::Init()
+{
+ //creates an environment table for the debugger
+
+ sq_newtable(_v);
+ sq_getstackobj(_v,-1,&_debugroot);
+ sq_addref(_v,&_debugroot);
+
+ //creates a emptyslot to store the watches
+ sq_pushstring(_v,_SC("watches"),-1);
+ sq_pushnull(_v);
+ sq_createslot(_v,-3);
+
+ sq_pushstring(_v,_SC("beginelement"),-1);
+ sq_pushuserpointer(_v,this);
+ sq_newclosure(_v,beginelement,1);
+ sq_setparamscheck(_v,2,_SC(".s"));
+ sq_createslot(_v,-3);
+
+ sq_pushstring(_v,_SC("endelement"),-1);
+ sq_pushuserpointer(_v,this);
+ sq_newclosure(_v,endelement,1);
+ sq_setparamscheck(_v,2,_SC(".s"));
+ sq_createslot(_v,-3);
+
+ sq_pushstring(_v,_SC("attribute"),-1);
+ sq_pushuserpointer(_v,this);
+ sq_newclosure(_v,attribute,1);
+ sq_setparamscheck(_v,3,_SC(".ss"));
+ sq_createslot(_v,-3);
+
+ sq_pop(_v,1);
+
+ //stores debug hook and error handler in the registry
+ sq_pushregistrytable(_v);
+
+ sq_pushstring(_v,SQDBG_DEBUG_HOOK,-1);
+ sq_pushuserpointer(_v,this);
+ sq_newclosure(_v,debug_hook,1);
+ sq_createslot(_v,-3);
+
+ sq_pushstring(_v,SQDBG_ERROR_HANDLER,-1);
+ sq_pushuserpointer(_v,this);
+ sq_newclosure(_v,error_handler,1);
+ sq_createslot(_v,-3);
+
+
+ sq_pop(_v,1);
+
+ //sets the error handlers
+ SetErrorHandlers();
+ return true;
+}
+
+bool SQDbgServer::ReadMsg()
+{
+ return false;
+}
+
+void SQDbgServer::BusyWait()
+{
+ while( !ReadMsg() )
+ sleep(0);
+}
+
+void SQDbgServer::SendChunk(const SQChar *chunk)
+{
+ char *buf=NULL;
+ int buf_len=0;
+#ifdef _UNICODE
+ buf_len=(int)scstrlen(chunk)+1;
+ buf=(char *)sq_getscratchpad(_v,(buf_len)*3);
+ wcstombs((char *)buf,chunk,buf_len);
+#else
+ buf_len=(int)scstrlen(chunk);
+ buf=(char *)chunk;
+#endif
+ send(_endpoint,(const char*)buf,(int)strlen((const char *)buf),0);
+}
+
+
+void SQDbgServer::Terminated()
+{
+ BeginElement(_SC("terminated"));
+ EndElement(_SC("terminated"));
+ ::usleep(200);
+}
+
+void SQDbgServer::Hook(int type,int line,const SQChar *src,const SQChar *func)
+{
+ switch(_state){
+ case eDBG_Running:
+ if(type==_SC('l') && _breakpoints.size()) {
+ BreakPointSetItor itr = _breakpoints.find(BreakPoint(line,src));
+ if(itr != _breakpoints.end()) {
+ Break(line,src,_SC("breakpoint"));
+ BreakExecution();
+ }
+ }
+ break;
+ case eDBG_Suspended:
+ _nestedcalls=0;
+ case eDBG_StepOver:
+ switch(type){
+ case _SC('l'):
+ if(_nestedcalls==0) {
+ Break(line,src,_SC("step"));
+ BreakExecution();
+ }
+ break;
+ case _SC('c'):
+ _nestedcalls++;
+ break;
+ case _SC('r'):
+ if(_nestedcalls==0){
+ _nestedcalls=0;
+
+ }else{
+ _nestedcalls--;
+ }
+ break;
+ }
+ break;
+ case eDBG_StepInto:
+ switch(type){
+ case _SC('l'):
+ _nestedcalls=0;
+ Break(line,src,_SC("step"));
+ BreakExecution();
+ break;
+
+ }
+ break;
+ case eDBG_StepReturn:
+ switch(type){
+ case _SC('l'):
+ break;
+ case _SC('c'):
+ _nestedcalls++;
+ break;
+ case _SC('r'):
+ if(_nestedcalls==0){
+ _nestedcalls=0;
+ _state=eDBG_StepOver;
+ }else{
+ _nestedcalls--;
+ }
+
+ break;
+ }
+ break;
+ case eDBG_Disabled:
+ break;
+ }
+}
+
+
+#define MSG_ID(x,y) ((y<<8)|x)
+//ab Add Breakpoint
+//rb Remove Breakpoint
+//sp Suspend
+void SQDbgServer::ParseMsg(const char *msg)
+{
+
+ switch(*((unsigned short *)msg)){
+ case MSG_ID('a','b'): {
+ BreakPoint bp;
+ if(ParseBreakpoint(msg+3,bp)){
+ AddBreakpoint(bp);
+ scprintf(_SC("added bp %d %s\n"),bp._line,bp._src.c_str());
+ }
+ else
+ scprintf(_SC("error parsing add breakpoint"));
+ }
+ break;
+ case MSG_ID('r','b'): {
+ BreakPoint bp;
+ if(ParseBreakpoint(msg+3,bp)){
+ RemoveBreakpoint(bp);
+ scprintf(_SC("removed bp %d %s\n"),bp._line,bp._src.c_str());
+ }else
+ scprintf(_SC("error parsing remove breakpoint"));
+ }
+ break;
+ case MSG_ID('g','o'):
+ if(_state!=eDBG_Running){
+ _state=eDBG_Running;
+ BeginDocument();
+ BeginElement(_SC("resumed"));
+ EndElement(_SC("resumed"));
+ EndDocument();
+// Send(_SC("<resumed/>\r\n"));
+ scprintf(_SC("go (execution resumed)\n"));
+ }
+ break;
+ case MSG_ID('s','p'):
+ if(_state!=eDBG_Suspended){
+ _state=eDBG_Suspended;
+ scprintf(_SC("suspend\n"));
+ }
+ break;
+ case MSG_ID('s','o'):
+ if(_state==eDBG_Suspended){
+ _state=eDBG_StepOver;
+ }
+ break;
+ case MSG_ID('s','i'):
+ if(_state==eDBG_Suspended){
+ _state=eDBG_StepInto;
+ scprintf(_SC("step into\n"));
+ }
+ break;
+ case MSG_ID('s','r'):
+ if(_state==eDBG_Suspended){
+ _state=eDBG_StepReturn;
+ scprintf(_SC("step return\n"));
+ }
+ break;
+ case MSG_ID('d','i'):
+ if(_state!=eDBG_Disabled){
+ _state=eDBG_Disabled;
+ scprintf(_SC("disabled\n"));
+ }
+ break;
+ case MSG_ID('a','w'): {
+ Watch w;
+ if(ParseWatch(msg+3,w))
+ {
+ AddWatch(w);
+ scprintf(_SC("added watch %d %s\n"),w._id,w._exp.c_str());
+ }
+ else
+ scprintf(_SC("error parsing add watch"));
+ }
+ break;
+ case MSG_ID('r','w'): {
+ int id;
+ if(ParseRemoveWatch(msg+3,id))
+ {
+ RemoveWatch(id);
+ scprintf(_SC("added watch %d\n"),id);
+ }
+ else
+ scprintf(_SC("error parsing remove watch"));
+ }
+ break;
+ case MSG_ID('t','r'):
+ scprintf(_SC("terminate from user\n"));
+ break;
+ case MSG_ID('r','d'):
+ scprintf(_SC("ready\n"));
+ _ready=true;
+ break;
+ default:
+ scprintf(_SC("unknown packet"));
+
+ }
+}
+
+/*
+ see copyright notice in sqrdbg.h
+*/
+bool SQDbgServer::ParseBreakpoint(const char *msg,BreakPoint &out)
+{
+ static char stemp[MAX_BP_PATH];
+ char *ep=NULL;
+ out._line=strtoul(msg,&ep,16);
+ if(ep==msg || (*ep)!=':')return false;
+
+ char *dest=stemp;
+ ep++;
+ while((*ep)!='\n' && (*ep)!='\0')
+ {
+ *dest=*ep;
+ *dest++;*ep++;
+ }
+ *dest='\0';
+ *dest++;
+ *dest='\0';
+#ifdef _UNICODE
+ int len=(int)strlen(stemp);
+ SQChar *p=sq_getscratchpad(_v,(SQInteger)(mbstowcs(NULL,stemp,len)+2)*sizeof(SQChar));
+ size_t destlen=mbstowcs(p,stemp,len);
+ p[destlen]=_SC('\0');
+ out._src=p;
+#else
+ out._src=stemp;
+#endif
+ return true;
+}
+
+bool SQDbgServer::ParseWatch(const char *msg,Watch &out)
+{
+ char *ep=NULL;
+ out._id=strtoul(msg,&ep,16);
+ if(ep==msg || (*ep)!=':')return false;
+
+ //char *dest=out._src;
+ ep++;
+ while((*ep)!='\n' && (*ep)!='\0')
+ {
+ out._exp.append(1,*ep);
+ *ep++;
+ }
+ return true;
+}
+
+bool SQDbgServer::ParseRemoveWatch(const char *msg,int &id)
+{
+ char *ep=NULL;
+ id=strtoul(msg,&ep,16);
+ if(ep==msg)return false;
+ return true;
+}
+
+
+void SQDbgServer::BreakExecution()
+{
+ _state=eDBG_Suspended;
+ while(_state==eDBG_Suspended){
+ if(SQ_FAILED(sq_rdbg_update(this)))
+ exit(0);
+ usleep(10);
+ }
+}
+
+//COMMANDS
+void SQDbgServer::AddBreakpoint(BreakPoint &bp)
+{
+ _breakpoints.insert(bp);
+ BeginDocument();
+ BeginElement(_SC("addbreakpoint"));
+ Attribute(_SC("line"),IntToString(bp._line));
+ Attribute(_SC("src"),bp._src.c_str());
+ EndElement(_SC("addbreakpoint"));
+ EndDocument();
+}
+
+void SQDbgServer::AddWatch(Watch &w)
+{
+ _watches.insert(w);
+}
+
+void SQDbgServer::RemoveWatch(int id)
+{
+ WatchSetItor itor=_watches.find(Watch(id,_SC("")));
+ if(itor==_watches.end()){
+ BeginDocument();
+ BeginElement(_SC("error"));
+ Attribute(_SC("desc"),_SC("the watch does not exists"));
+ EndElement(_SC("error"));
+ EndDocument();
+ }
+ else{
+ _watches.erase(itor);
+ scprintf(_SC("removed watch %d\n"),id);
+ }
+}
+
+void SQDbgServer::RemoveBreakpoint(BreakPoint &bp)
+{
+ BreakPointSetItor itor=_breakpoints.find(bp);
+ if(itor==_breakpoints.end()){
+ BeginDocument();
+ BeginElement(_SC("break"));
+ Attribute(_SC("desc"),_SC("the breakpoint doesn't exists"));
+ EndElement(_SC("break"));
+ EndDocument();
+ }
+ else{
+ BeginDocument();
+ BeginElement(_SC("removebreakpoint"));
+ Attribute(_SC("line"),IntToString(bp._line));
+ Attribute(_SC("src"),bp._src.c_str());
+ EndElement(_SC("removebreakpoint"));
+ EndDocument();
+ _breakpoints.erase(itor);
+ }
+}
+
+void SQDbgServer::Break(int line,const SQChar *src,const SQChar *type,const SQChar *error)
+{
+ if(!error){
+ BeginDocument();
+ BeginElement(_SC("break"));
+ Attribute(_SC("line"),IntToString(line));
+ Attribute(_SC("src"),src);
+ Attribute(_SC("type"),type);
+ SerializeState();
+ EndElement(_SC("break"));
+ EndDocument();
+ }else{
+ BeginDocument();
+ BeginElement(_SC("break"));
+ Attribute(_SC("line"),IntToString(line));
+ Attribute(_SC("src"),src);
+ Attribute(_SC("type"),type);
+ Attribute(_SC("error"),error);
+ SerializeState();
+ EndElement(_SC("break"));
+ EndDocument();
+ }
+}
+
+void SQDbgServer::SerializeState()
+{
+ sq_pushnull(_v);
+ sq_setdebughook(_v);
+ sq_pushnull(_v);
+ sq_seterrorhandler(_v);
+ const SQChar *sz;
+ sq_pushobject(_v,_serializefunc);
+ sq_pushobject(_v,_debugroot);
+ sq_pushstring(_v,_SC("watches"),-1);
+ sq_newtable(_v);
+ for(WatchSetItor i=_watches.begin(); i!=_watches.end(); ++i)
+ {
+ sq_pushinteger(_v,i->_id);
+ sq_pushstring(_v,i->_exp.c_str(),(int)i->_exp.length());
+ sq_createslot(_v,-3);
+ }
+ sq_rawset(_v,-3);
+ if(SQ_SUCCEEDED(sq_call(_v,1,SQTrue,SQTrue))){
+ if(SQ_SUCCEEDED(sqstd_getblob(_v,-1,(SQUserPointer*)&sz)))
+ SendChunk(sz);
+ }
+ sq_pop(_v,2);
+
+ SetErrorHandlers();
+}
+
+
+void SQDbgServer::SetErrorHandlers()
+{
+ sq_pushregistrytable(_v);
+ sq_pushstring(_v,SQDBG_DEBUG_HOOK,-1);
+ sq_rawget(_v,-2);
+ sq_setdebughook(_v);
+ sq_pushstring(_v,SQDBG_ERROR_HANDLER,-1);
+ sq_rawget(_v,-2);
+ sq_seterrorhandler(_v);
+ sq_pop(_v,1);
+}
+
+void SQDbgServer::BeginElement(const SQChar *name)
+{
+ _xmlcurrentement++;
+ XMLElementState *self = &xmlstate[_xmlcurrentement];
+ scstrcpy(self->name,name);
+ self->haschildren = false;
+ if(_xmlcurrentement > 0) {
+ XMLElementState *parent = &xmlstate[_xmlcurrentement-1];
+ if(!parent->haschildren) {
+ SendChunk(_SC(">")); // closes the parent tag
+ parent->haschildren = true;
+ }
+ }
+ _scratchstring.resize(2+scstrlen(name));
+ scsprintf(&_scratchstring[0],_SC("<%s"),name);
+ SendChunk(&_scratchstring[0]);
+}
+
+void SQDbgServer::Attribute(const SQChar *name,const SQChar *value)
+{
+ XMLElementState *self = &xmlstate[_xmlcurrentement];
+ assert(!self->haschildren); //cannot have attributes if already has children
+ const SQChar *escval = escape_xml(value);
+ _scratchstring.resize(5+scstrlen(name)+scstrlen(escval));
+ scsprintf(&_scratchstring[0],_SC(" %s=\"%s\""),name,escval);
+ SendChunk(&_scratchstring[0]);
+}
+
+void SQDbgServer::EndElement(const SQChar *name)
+{
+ XMLElementState *self = &xmlstate[_xmlcurrentement];
+ assert(scstrcmp(self->name,name) == 0);
+ if(self->haschildren) {
+ _scratchstring.resize(4+scstrlen(name));
+ scsprintf(&_scratchstring[0],_SC("</%s>"),name);
+ SendChunk(&_scratchstring[0]);
+
+ }
+ else {
+ SendChunk(_SC("/>"));
+ }
+ _xmlcurrentement--;
+}
+
+void SQDbgServer::EndDocument()
+{
+ SendChunk(_SC("\r\n"));
+}
+
+//this can be done much better/faster(do we need that?)
+const SQChar *SQDbgServer::escape_xml(const SQChar *s)
+{
+ SQChar *temp=sq_getscratchpad(_v,((int)scstrlen(s)*6) + sizeof(SQChar));
+ SQChar *dest=temp;
+ while(*s!=_SC('\0')){
+ int i=0;
+ bool escaped=false;
+ while(g_escapes[i].esc!=NULL){
+ if(*s==g_escapes[i].c){
+ scstrcpy(dest,g_escapes[i].esc);
+ dest+=scstrlen(g_escapes[i].esc);
+ escaped=true;
+ break;
+ }
+ i++;
+ }
+ if(!escaped){*dest=*s;*dest++;}
+ *s++;
+ }
+ *dest=_SC('\0');
+ return temp;
+
+}
--- /dev/null
+#ifndef _SQ_DBGSERVER_H_
+#define _SQ_DBGSERVER_H_
+
+#define MAX_BP_PATH 512
+#define MAX_MSG_LEN 2049
+
+#include <set>
+#include <string>
+#include <vector>
+
+#ifdef _WIN32
+#include <winsock.h>
+#define sqdbg_closesocket(x) closesocket((x))
+typedef socklen_t int;
+#else
+#include <unistd.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <fcntl.h>
+
+#define sqdbg_closesocket(x) close((x))
+typedef int SOCKET;
+typedef struct timeval TIMEVAL;
+#define SOCKET_ERROR -1
+#define INVALID_SOCKET -1
+#endif
+
+typedef std::basic_string<SQChar> SQDBGString;
+
+inline bool dbg_less(const SQChar *x,const SQChar *y)
+{
+ // [SuperTux] commented out to avoid compiler warning
+ //int n = 0;
+ do {
+ int xl = *x == '\\' ? '/' : tolower(*x);
+ int yl = *y == '\\' ? '/' : tolower(*y);
+ int diff = xl - yl;
+ if(diff != 0)
+ return diff > 0?true:false;
+ x++; y++;
+ }while(*x != 0 && *y != 0);
+ return false;
+}
+
+struct BreakPoint{
+ BreakPoint(){_line=0;}
+ BreakPoint(int line, const SQChar *src){ _line = line; _src = src; }
+ BreakPoint(const BreakPoint& bp){ _line = bp._line; _src=bp._src; }
+ inline bool operator<(const BreakPoint& bp) const
+ {
+ if(_line<bp._line)
+ return true;
+ if(_line==bp._line){
+ return dbg_less(_src.c_str(),bp._src.c_str());
+ }
+ return false;
+ }
+
+ int _line;
+ SQDBGString _src;
+};
+
+struct Watch{
+ Watch() { _id = 0; }
+ Watch(int id,const SQChar *exp) { _id = id; _exp = exp; }
+ Watch(const Watch &w) { _id = w._id; _exp = w._exp; }
+ bool operator<(const Watch& w) const { return _id<w._id; }
+ bool operator==(const Watch& w) const { return _id == w._id; }
+ int _id;
+ SQDBGString _exp;
+};
+
+typedef std::set<BreakPoint> BreakPointSet;
+typedef BreakPointSet::iterator BreakPointSetItor;
+
+typedef std::set<Watch> WatchSet;
+typedef WatchSet::iterator WatchSetItor;
+
+typedef std::vector<SQChar> SQCharVec;
+struct SQDbgServer{
+public:
+ enum eDbgState{
+ eDBG_Running,
+ eDBG_StepOver,
+ eDBG_StepInto,
+ eDBG_StepReturn,
+ eDBG_Suspended,
+ eDBG_Disabled,
+ };
+
+ SQDbgServer(HSQUIRRELVM v);
+ ~SQDbgServer();
+ bool Init();
+ //returns true if a message has been received
+ bool WaitForClient();
+ bool ReadMsg();
+ void BusyWait();
+ void Hook(int type,int line,const SQChar *src,const SQChar *func);
+ void ParseMsg(const char *msg);
+ bool ParseBreakpoint(const char *msg,BreakPoint &out);
+ bool ParseWatch(const char *msg,Watch &out);
+ bool ParseRemoveWatch(const char *msg,int &id);
+ void Terminated();
+ //
+ void BreakExecution();
+ void Send(const SQChar *s,...);
+ void SendChunk(const SQChar *chunk);
+ void Break(int line,const SQChar *src,const SQChar *type,const SQChar *error=NULL);
+
+
+ void SerializeState();
+ //COMMANDS
+ void AddBreakpoint(BreakPoint &bp);
+ void AddWatch(Watch &w);
+ void RemoveWatch(int id);
+ void RemoveBreakpoint(BreakPoint &bp);
+
+ //
+ void SetErrorHandlers();
+
+ //XML RELATED STUFF///////////////////////
+ #define MAX_NESTING 10
+ struct XMLElementState {
+ SQChar name[256];
+ bool haschildren;
+ };
+
+ XMLElementState xmlstate[MAX_NESTING];
+ int _xmlcurrentement;
+
+ void BeginDocument() { _xmlcurrentement = -1; }
+ void BeginElement(const SQChar *name);
+ void Attribute(const SQChar *name, const SQChar *value);
+ void EndElement(const SQChar *name);
+ void EndDocument();
+
+ const SQChar *escape_xml(const SQChar *x);
+ //////////////////////////////////////////////
+ HSQUIRRELVM _v;
+ HSQOBJECT _debugroot;
+ eDbgState _state;
+ SOCKET _accept;
+ SOCKET _endpoint;
+ BreakPointSet _breakpoints;
+ WatchSet _watches;
+ int _recursionlevel;
+ int _maxrecursion;
+ int _nestedcalls;
+ bool _ready;
+ bool _autoupdate;
+ HSQOBJECT _serializefunc;
+ SQCharVec _scratchstring;
+
+};
+
+#endif //_SQ_DBGSERVER_H_
--- /dev/null
+/*
+ see copyright notice in sqrdbg.h
+*/
+#include <squirrel.h>
+#include "sqrdbg.h"
+#include "sqdbgserver.h"
+SQInteger debug_hook(HSQUIRRELVM v);
+SQInteger error_handler(HSQUIRRELVM v);
+
+#include "serialize_state.inl"
+
+HSQREMOTEDBG sq_rdbg_init(HSQUIRRELVM v,unsigned short port,SQBool autoupdate)
+{
+ sockaddr_in bindaddr;
+#ifdef _WIN32
+ WSADATA wsadata;
+ if (WSAStartup (MAKEWORD(1,1), &wsadata) != 0){
+ return NULL;
+ }
+#endif
+
+ SQDbgServer *rdbg = new SQDbgServer(v);
+ rdbg->_autoupdate = autoupdate?true:false;
+ rdbg->_accept = socket(AF_INET,SOCK_STREAM,0);
+ bindaddr.sin_family = AF_INET;
+ bindaddr.sin_port = htons(port);
+ bindaddr.sin_addr.s_addr = htonl (INADDR_ANY);
+ if(bind(rdbg->_accept,(sockaddr*)&bindaddr,sizeof(bindaddr))==SOCKET_ERROR){
+ delete rdbg;
+ sq_throwerror(v,_SC("failed to bind the socket"));
+ return NULL;
+ }
+ if(!rdbg->Init()) {
+ delete rdbg;
+ sq_throwerror(v,_SC("failed to initialize the debugger"));
+ return NULL;
+ }
+
+ return rdbg;
+}
+
+SQRESULT sq_rdbg_waitforconnections(HSQREMOTEDBG rdbg)
+{
+ if(SQ_FAILED(sq_compilebuffer(rdbg->_v,serialize_state_nut,(SQInteger)scstrlen(serialize_state_nut),_SC("SERIALIZE_STATE"),SQFalse))) {
+ sq_throwerror(rdbg->_v,_SC("error compiling the serialization function"));
+ }
+ sq_getstackobj(rdbg->_v,-1,&rdbg->_serializefunc);
+ sq_addref(rdbg->_v,&rdbg->_serializefunc);
+ sq_pop(rdbg->_v,1);
+
+ sockaddr_in cliaddr;
+ socklen_t addrlen=sizeof(cliaddr);
+ if(listen(rdbg->_accept,0)==SOCKET_ERROR)
+ return sq_throwerror(rdbg->_v,_SC("error on listen(socket)"));
+ rdbg->_endpoint = accept(rdbg->_accept,(sockaddr*)&cliaddr,&addrlen);
+ //do not accept any other connection
+ sqdbg_closesocket(rdbg->_accept);
+ rdbg->_accept = INVALID_SOCKET;
+ if(rdbg->_endpoint==INVALID_SOCKET){
+ return sq_throwerror(rdbg->_v,_SC("error accept(socket)"));
+ }
+ while(!rdbg->_ready){
+ sq_rdbg_update(rdbg);
+ }
+ return SQ_OK;
+}
+
+SQRESULT sq_rdbg_update(HSQREMOTEDBG rdbg)
+{
+ TIMEVAL time;
+ time.tv_sec=0;
+ time.tv_usec=0;
+ fd_set read_flags;
+ FD_ZERO(&read_flags);
+ FD_SET(rdbg->_endpoint, &read_flags);
+ select(FD_SETSIZE, &read_flags, NULL, NULL, &time);
+
+ if(FD_ISSET(rdbg->_endpoint,&read_flags)){
+ char temp[1024];
+ int size=0;
+ char c,prev=0;
+ memset(&temp,0,sizeof(temp));
+ int res;
+ FD_CLR(rdbg->_endpoint, &read_flags);
+ while((res = recv(rdbg->_endpoint,&c,1,0))>0){
+
+ if(c=='\n')break;
+ if(c!='\r'){
+ temp[size]=c;
+ prev=c;
+ size++;
+ }
+ }
+ switch(res){
+ case 0:
+ return sq_throwerror(rdbg->_v,_SC("disconnected"));
+ case SOCKET_ERROR:
+ return sq_throwerror(rdbg->_v,_SC("socket error"));
+ }
+
+ temp[size]=0;
+ temp[size+1]=0;
+ rdbg->ParseMsg(temp);
+ }
+ return SQ_OK;
+}
+
+SQInteger debug_hook(HSQUIRRELVM v)
+{
+ SQUserPointer up;
+ SQInteger event_type,line;
+ const SQChar *src,*func;
+ sq_getinteger(v,2,&event_type);
+ sq_getstring(v,3,&src);
+ sq_getinteger(v,4,&line);
+ sq_getstring(v,5,&func);
+ sq_getuserpointer(v,-1,&up);
+ HSQREMOTEDBG rdbg = (HSQREMOTEDBG)up;
+ rdbg->Hook(event_type,line,src,func);
+ if(rdbg->_autoupdate) {
+ if(SQ_FAILED(sq_rdbg_update(rdbg)))
+ return sq_throwerror(v,_SC("socket failed"));
+ }
+ return 0;
+}
+
+SQInteger error_handler(HSQUIRRELVM v)
+{
+ SQUserPointer up;
+ const SQChar *sErr=NULL;
+ const SQChar *fn=_SC("unknown");
+ const SQChar *src=_SC("unknown");
+ int line=-1;
+ SQStackInfos si;
+ sq_getuserpointer(v,-1,&up);
+ HSQREMOTEDBG rdbg=(HSQREMOTEDBG)up;
+ if(SQ_SUCCEEDED(sq_stackinfos(v,1,&si)))
+ {
+ if(si.funcname)fn=si.funcname;
+ if(si.source)src=si.source;
+ line=si.line;
+ scprintf(_SC("*FUNCTION [%s] %s line [%d]\n"),fn,src,si.line);
+ }
+ if(sq_gettop(v)>=1){
+ if(SQ_SUCCEEDED(sq_getstring(v,2,&sErr))) {
+ scprintf(_SC("\nAN ERROR HAS OCCURED [%s]\n"),sErr);
+ rdbg->Break(si.line,src,_SC("error"),sErr);
+ }
+ else{
+ scprintf(_SC("\nAN ERROR HAS OCCURED [unknown]\n"));
+ rdbg->Break(si.line,src,_SC("error"),_SC("unknown"));
+ }
+ }
+ rdbg->BreakExecution();
+ return 0;
+}
+
+
+SQRESULT sq_rdbg_shutdown(HSQREMOTEDBG rdbg)
+{
+ delete rdbg;
+#ifdef _WIN32
+ WSACleanup();
+#endif
+ return SQ_OK;
+}
--- /dev/null
+/*
+Copyright (c) 2003-2005 Alberto Demichelis
+
+This software is provided 'as-is', without any
+express or implied warranty. In no event will the
+authors be held liable for any damages arising from
+the use of this software.
+
+Permission is granted to anyone to use this software
+for any purpose, including commercial applications,
+and to alter it and redistribute it freely, subject
+to the following restrictions:
+
+ 1. The origin of this software must not be
+ misrepresented; you must not claim that
+ you wrote the original software. If you
+ use this software in a product, an
+ acknowledgment in the product
+ documentation would be appreciated but is
+ not required.
+
+ 2. Altered source versions must be plainly
+ marked as such, and must not be
+ misrepresented as being the original
+ software.
+
+ 3. This notice may not be removed or
+ altered from any source distribution.
+
+*/
+#ifndef _SQ_RDBG_H_
+#define _SQ_RDBG_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct SQDbgServer;
+typedef SQDbgServer* HSQREMOTEDBG;
+
+HSQREMOTEDBG sq_rdbg_init(HSQUIRRELVM v,unsigned short port,SQBool autoupdate);
+SQRESULT sq_rdbg_waitforconnections(HSQREMOTEDBG rdbg);
+SQRESULT sq_rdbg_shutdown(HSQREMOTEDBG rdbg);
+SQRESULT sq_rdbg_update(HSQREMOTEDBG rdbg);
+
+#ifdef __cplusplus
+} /*extern "C"*/
+#endif
+
+#endif //_SQ_RDBG_H_
--- /dev/null
+/* see copyright notice in squirrel.h */
+#include <squirrel.h>
+#include <sqstdaux.h>
+#include <assert.h>
+
+void sqstd_printcallstack(HSQUIRRELVM v)
+{
+ SQPRINTFUNCTION pf = sq_getprintfunc(v);
+ if(pf) {
+ SQStackInfos si;
+ SQInteger i;
+ SQBool b;
+ SQFloat f;
+ const SQChar *s;
+ SQInteger level=1; //1 is to skip this function that is level 0
+ const SQChar *name=0;
+ SQInteger seq=0;
+ pf(v,_SC("\nCALLSTACK\n"));
+ while(SQ_SUCCEEDED(sq_stackinfos(v,level,&si)))
+ {
+ const SQChar *fn=_SC("unknown");
+ const SQChar *src=_SC("unknown");
+ if(si.funcname)fn=si.funcname;
+ if(si.source)src=si.source;
+ pf(v,_SC("*FUNCTION [%s()] %s line [%d]\n"),fn,src,si.line);
+ level++;
+ }
+ level=0;
+ pf(v,_SC("\nLOCALS\n"));
+
+ for(level=0;level<10;level++){
+ seq=0;
+ while((name = sq_getlocal(v,level,seq)))
+ {
+ seq++;
+ switch(sq_gettype(v,-1))
+ {
+ case OT_NULL:
+ pf(v,_SC("[%s] NULL\n"),name);
+ break;
+ case OT_INTEGER:
+ sq_getinteger(v,-1,&i);
+ pf(v,_SC("[%s] %d\n"),name,i);
+ break;
+ case OT_FLOAT:
+ sq_getfloat(v,-1,&f);
+ pf(v,_SC("[%s] %.14g\n"),name,f);
+ break;
+ case OT_USERPOINTER:
+ pf(v,_SC("[%s] USERPOINTER\n"),name);
+ break;
+ case OT_STRING:
+ sq_getstring(v,-1,&s);
+ pf(v,_SC("[%s] \"%s\"\n"),name,s);
+ break;
+ case OT_TABLE:
+ pf(v,_SC("[%s] TABLE\n"),name);
+ break;
+ case OT_ARRAY:
+ pf(v,_SC("[%s] ARRAY\n"),name);
+ break;
+ case OT_CLOSURE:
+ pf(v,_SC("[%s] CLOSURE\n"),name);
+ break;
+ case OT_NATIVECLOSURE:
+ pf(v,_SC("[%s] NATIVECLOSURE\n"),name);
+ break;
+ case OT_GENERATOR:
+ pf(v,_SC("[%s] GENERATOR\n"),name);
+ break;
+ case OT_USERDATA:
+ pf(v,_SC("[%s] USERDATA\n"),name);
+ break;
+ case OT_THREAD:
+ pf(v,_SC("[%s] THREAD\n"),name);
+ break;
+ case OT_CLASS:
+ pf(v,_SC("[%s] CLASS\n"),name);
+ break;
+ case OT_INSTANCE:
+ pf(v,_SC("[%s] INSTANCE\n"),name);
+ break;
+ case OT_WEAKREF:
+ pf(v,_SC("[%s] WEAKREF\n"),name);
+ break;
+ case OT_BOOL:{
+ sq_getbool(v,-1,&b);
+ pf(v,_SC("[%s] %s\n"),name,b?_SC("true"):_SC("false"));
+ }
+ break;
+ default: assert(0); break;
+ }
+ sq_pop(v,1);
+ }
+ }
+ }
+}
+
+static SQInteger _sqstd_aux_printerror(HSQUIRRELVM v)
+{
+ SQPRINTFUNCTION pf = sq_getprintfunc(v);
+ if(pf) {
+ const SQChar *sErr = 0;
+ if(sq_gettop(v)>=1) {
+ if(SQ_SUCCEEDED(sq_getstring(v,2,&sErr))) {
+ pf(v,_SC("\nAN ERROR HAS OCCURED [%s]\n"),sErr);
+ }
+ else{
+ pf(v,_SC("\nAN ERROR HAS OCCURED [unknown]\n"));
+ }
+ sqstd_printcallstack(v);
+ }
+ }
+ return 0;
+}
+
+void _sqstd_compiler_error(HSQUIRRELVM v,const SQChar *sErr,const SQChar *sSource,SQInteger line,SQInteger column)
+{
+ SQPRINTFUNCTION pf = sq_getprintfunc(v);
+ if(pf) {
+ pf(v,_SC("%s line = (%d) column = (%d) : error %s\n"),sSource,line,column,sErr);
+ }
+}
+
+void sqstd_seterrorhandlers(HSQUIRRELVM v)
+{
+ sq_setcompilererrorhandler(v,_sqstd_compiler_error);
+ sq_newclosure(v,_sqstd_aux_printerror,0);
+ sq_seterrorhandler(v);
+}
--- /dev/null
+/* see copyright notice in squirrel.h */
+#include <new>
+#include <squirrel.h>
+#include <sqstdio.h>
+#include <string.h>
+#include <sqstdblob.h>
+#include "sqstdstream.h"
+#include "sqstdblobimpl.h"
+
+#define SQSTD_BLOB_TYPE_TAG (SQSTD_STREAM_TYPE_TAG | 0x00000002)
+
+//Blob
+
+
+#define SETUP_BLOB(v) \
+ SQBlob *self = NULL; \
+ { if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) \
+ return SQ_ERROR; }
+
+
+static SQInteger _blob_resize(HSQUIRRELVM v)
+{
+ SETUP_BLOB(v);
+ SQInteger size;
+ sq_getinteger(v,2,&size);
+ if(!self->Resize(size))
+ return sq_throwerror(v,_SC("resize failed"));
+ return 0;
+}
+
+static void __swap_dword(unsigned int *n)
+{
+ *n=(unsigned int)(((*n&0xFF000000)>>24) |
+ ((*n&0x00FF0000)>>8) |
+ ((*n&0x0000FF00)<<8) |
+ ((*n&0x000000FF)<<24));
+}
+
+static void __swap_word(unsigned short *n)
+{
+ *n=(unsigned short)((*n>>8)&0x00FF)| ((*n<<8)&0xFF00);
+}
+
+static SQInteger _blob_swap4(HSQUIRRELVM v)
+{
+ SETUP_BLOB(v);
+ SQInteger num=(self->Len()-(self->Len()%4))>>2;
+ unsigned int *t=(unsigned int *)self->GetBuf();
+ for(SQInteger i = 0; i < num; i++) {
+ __swap_dword(&t[i]);
+ }
+ return 0;
+}
+
+static SQInteger _blob_swap2(HSQUIRRELVM v)
+{
+ SETUP_BLOB(v);
+ SQInteger num=(self->Len()-(self->Len()%2))>>1;
+ unsigned short *t = (unsigned short *)self->GetBuf();
+ for(SQInteger i = 0; i < num; i++) {
+ __swap_word(&t[i]);
+ }
+ return 0;
+}
+
+static SQInteger _blob__set(HSQUIRRELVM v)
+{
+ SETUP_BLOB(v);
+ SQInteger idx,val;
+ sq_getinteger(v,2,&idx);
+ sq_getinteger(v,3,&val);
+ if(idx < 0 || idx >= self->Len())
+ return sq_throwerror(v,_SC("index out of range"));
+ ((unsigned char *)self->GetBuf())[idx] = (unsigned char) val;
+ sq_push(v,3);
+ return 1;
+}
+
+static SQInteger _blob__get(HSQUIRRELVM v)
+{
+ SETUP_BLOB(v);
+ SQInteger idx;
+ sq_getinteger(v,2,&idx);
+ if(idx < 0 || idx >= self->Len())
+ return sq_throwerror(v,_SC("index out of range"));
+ sq_pushinteger(v,((unsigned char *)self->GetBuf())[idx]);
+ return 1;
+}
+
+static SQInteger _blob__nexti(HSQUIRRELVM v)
+{
+ SETUP_BLOB(v);
+ if(sq_gettype(v,2) == OT_NULL) {
+ sq_pushinteger(v, 0);
+ return 1;
+ }
+ SQInteger idx;
+ if(SQ_SUCCEEDED(sq_getinteger(v, 2, &idx))) {
+ if(idx+1 < self->Len()) {
+ sq_pushinteger(v, idx+1);
+ return 1;
+ }
+ sq_pushnull(v);
+ return 1;
+ }
+ return sq_throwerror(v,_SC("internal error (_nexti) wrong argument type"));
+}
+
+static SQInteger _blob__typeof(HSQUIRRELVM v)
+{
+ sq_pushstring(v,_SC("blob"),-1);
+ return 1;
+}
+
+static SQInteger _blob_releasehook(SQUserPointer p, SQInteger size)
+{
+ SQBlob *self = (SQBlob*)p;
+ delete self;
+ return 1;
+}
+
+static SQInteger _blob_constructor(HSQUIRRELVM v)
+{
+ SQInteger nparam = sq_gettop(v);
+ SQInteger size = 0;
+ if(nparam == 2) {
+ sq_getinteger(v, 2, &size);
+ }
+ if(size < 0) return sq_throwerror(v, _SC("cannot create blob with negative size"));
+ SQBlob *b = new SQBlob(size);
+ if(SQ_FAILED(sq_setinstanceup(v,1,b))) {
+ delete b;
+ return sq_throwerror(v, _SC("cannot create blob with negative size"));
+ }
+ sq_setreleasehook(v,1,_blob_releasehook);
+ return 0;
+}
+
+#define _DECL_BLOB_FUNC(name,nparams,typecheck) {_SC(#name),_blob_##name,nparams,typecheck}
+static SQRegFunction _blob_methods[] = {
+ _DECL_BLOB_FUNC(constructor,-1,_SC("xn")),
+ _DECL_BLOB_FUNC(resize,2,_SC("xn")),
+ _DECL_BLOB_FUNC(swap2,1,_SC("x")),
+ _DECL_BLOB_FUNC(swap4,1,_SC("x")),
+ _DECL_BLOB_FUNC(_set,3,_SC("xnn")),
+ _DECL_BLOB_FUNC(_get,2,_SC("xn")),
+ _DECL_BLOB_FUNC(_typeof,1,_SC("x")),
+ _DECL_BLOB_FUNC(_nexti,2,_SC("x")),
+ {0,0,0,0}
+};
+
+
+
+//GLOBAL FUNCTIONS
+
+static SQInteger _g_blob_casti2f(HSQUIRRELVM v)
+{
+ SQInteger i;
+ sq_getinteger(v,2,&i);
+ sq_pushfloat(v,*((SQFloat *)&i));
+ return 1;
+}
+
+static SQInteger _g_blob_castf2i(HSQUIRRELVM v)
+{
+ SQFloat f;
+ sq_getfloat(v,2,&f);
+ sq_pushinteger(v,*((SQInteger *)&f));
+ return 1;
+}
+
+static SQInteger _g_blob_swap2(HSQUIRRELVM v)
+{
+ SQInteger i;
+ sq_getinteger(v,2,&i);
+ short s=(short)i;
+ sq_pushinteger(v,(s<<8)|((s>>8)&0x00FF));
+ return 1;
+}
+
+static SQInteger _g_blob_swap4(HSQUIRRELVM v)
+{
+ SQInteger i;
+ sq_getinteger(v,2,&i);
+ unsigned int t4 = (unsigned int)i;
+ __swap_dword(&t4);
+ sq_pushinteger(v,(SQInteger)t4);
+ return 1;
+}
+
+static SQInteger _g_blob_swapfloat(HSQUIRRELVM v)
+{
+ SQFloat f;
+ sq_getfloat(v,2,&f);
+ __swap_dword((unsigned int *)&f);
+ sq_pushfloat(v,f);
+ return 1;
+}
+
+#define _DECL_GLOBALBLOB_FUNC(name,nparams,typecheck) {_SC(#name),_g_blob_##name,nparams,typecheck}
+static SQRegFunction bloblib_funcs[]={
+ _DECL_GLOBALBLOB_FUNC(casti2f,2,_SC(".n")),
+ _DECL_GLOBALBLOB_FUNC(castf2i,2,_SC(".n")),
+ _DECL_GLOBALBLOB_FUNC(swap2,2,_SC(".n")),
+ _DECL_GLOBALBLOB_FUNC(swap4,2,_SC(".n")),
+ _DECL_GLOBALBLOB_FUNC(swapfloat,2,_SC(".n")),
+ {0,0}
+};
+
+SQRESULT sqstd_getblob(HSQUIRRELVM v,SQInteger idx,SQUserPointer *ptr)
+{
+ SQBlob *blob;
+ if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG)))
+ return -1;
+ *ptr = blob->GetBuf();
+ return SQ_OK;
+}
+
+SQInteger sqstd_getblobsize(HSQUIRRELVM v,SQInteger idx)
+{
+ SQBlob *blob;
+ if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG)))
+ return -1;
+ return blob->Len();
+}
+
+SQUserPointer sqstd_createblob(HSQUIRRELVM v, SQInteger size)
+{
+ SQInteger top = sq_gettop(v);
+ sq_pushregistrytable(v);
+ sq_pushstring(v,_SC("std_blob"),-1);
+ if(SQ_SUCCEEDED(sq_get(v,-2))) {
+ sq_remove(v,-2); //removes the registry
+ sq_push(v,1); // push the this
+ sq_pushinteger(v,size); //size
+ SQBlob *blob = NULL;
+ if(SQ_SUCCEEDED(sq_call(v,2,SQTrue,SQFalse))
+ && SQ_SUCCEEDED(sq_getinstanceup(v,-1,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) {
+ sq_remove(v,-2);
+ return blob->GetBuf();
+ }
+ }
+ sq_settop(v,top);
+ return NULL;
+}
+
+SQRESULT sqstd_register_bloblib(HSQUIRRELVM v)
+{
+ return declare_stream(v,_SC("blob"),(SQUserPointer)SQSTD_BLOB_TYPE_TAG,_SC("std_blob"),_blob_methods,bloblib_funcs);
+}
+
--- /dev/null
+/* see copyright notice in squirrel.h */
+#ifndef _SQSTD_BLOBIMPL_H_
+#define _SQSTD_BLOBIMPL_H_
+
+struct SQBlob : public SQStream
+{
+ SQBlob(SQInteger size) {
+ _size = size;
+ _allocated = size;
+ _buf = (unsigned char *)sq_malloc(size);
+ memset(_buf, 0, _size);
+ _ptr = 0;
+ _owns = true;
+ }
+ virtual ~SQBlob() {
+ sq_free(_buf, _allocated);
+ }
+ SQInteger Write(void *buffer, SQInteger size) {
+ if(!CanAdvance(size)) {
+ GrowBufOf(_ptr + size - _size);
+ }
+ memcpy(&_buf[_ptr], buffer, size);
+ _ptr += size;
+ return size;
+ }
+ SQInteger Read(void *buffer,SQInteger size) {
+ SQInteger n = size;
+ if(!CanAdvance(size)) {
+ if((_size - _ptr) > 0)
+ n = _size - _ptr;
+ else return 0;
+ }
+ memcpy(buffer, &_buf[_ptr], n);
+ _ptr += n;
+ return n;
+ }
+ bool Resize(SQInteger n) {
+ if(!_owns) return false;
+ if(n != _allocated) {
+ unsigned char *newbuf = (unsigned char *)sq_malloc(n);
+ memset(newbuf,0,n);
+ if(_size > n)
+ memcpy(newbuf,_buf,n);
+ else
+ memcpy(newbuf,_buf,_size);
+ sq_free(_buf,_allocated);
+ _buf=newbuf;
+ _allocated = n;
+ if(_size > _allocated)
+ _size = _allocated;
+ if(_ptr > _allocated)
+ _ptr = _allocated;
+ }
+ return true;
+ }
+ bool GrowBufOf(SQInteger n)
+ {
+ bool ret = true;
+ if(_size + n > _allocated) {
+ if(_size + n > _size * 2)
+ ret = Resize(_size + n);
+ else
+ ret = Resize(_size * 2);
+ }
+ _size = _size + n;
+ return ret;
+ }
+ bool CanAdvance(SQInteger n) {
+ if(_ptr+n>_size)return false;
+ return true;
+ }
+ SQInteger Seek(SQInteger offset, SQInteger origin) {
+ switch(origin) {
+ case SQ_SEEK_SET:
+ if(offset > _size || offset < 0) return -1;
+ _ptr = offset;
+ break;
+ case SQ_SEEK_CUR:
+ if(_ptr + offset > _size || _ptr + offset < 0) return -1;
+ _ptr += offset;
+ break;
+ case SQ_SEEK_END:
+ if(_size + offset > _size || _size + offset < 0) return -1;
+ _ptr = _size + offset;
+ break;
+ default: return -1;
+ }
+ return 0;
+ }
+ bool IsValid() {
+ return _buf?true:false;
+ }
+ bool EOS() {
+ return _ptr == _size;
+ }
+ SQInteger Flush() { return 0; }
+ SQInteger Tell() { return _ptr; }
+ SQInteger Len() { return _size; }
+ SQUserPointer GetBuf(){ return _buf; }
+private:
+ SQInteger _size;
+ SQInteger _allocated;
+ SQInteger _ptr;
+ unsigned char *_buf;
+ bool _owns;
+};
+
+#endif //_SQSTD_BLOBIMPL_H_
--- /dev/null
+/* see copyright notice in squirrel.h */
+#include <new>
+#include <stdio.h>
+#include <squirrel.h>
+#include <sqstdio.h>
+#include "sqstdstream.h"
+
+#define SQSTD_FILE_TYPE_TAG (SQSTD_STREAM_TYPE_TAG | 0x00000001)
+//basic API
+SQFILE sqstd_fopen(const SQChar *filename ,const SQChar *mode)
+{
+#ifndef SQUNICODE
+ return (SQFILE)fopen(filename,mode);
+#else
+ return (SQFILE)_wfopen(filename,mode);
+#endif
+}
+
+SQInteger sqstd_fread(void* buffer, SQInteger size, SQInteger count, SQFILE file)
+{
+ return (SQInteger)fread(buffer,size,count,(FILE *)file);
+}
+
+SQInteger sqstd_fwrite(const SQUserPointer buffer, SQInteger size, SQInteger count, SQFILE file)
+{
+ return (SQInteger)fwrite(buffer,size,count,(FILE *)file);
+}
+
+SQInteger sqstd_fseek(SQFILE file, SQInteger offset, SQInteger origin)
+{
+ SQInteger realorigin;
+ switch(origin) {
+ case SQ_SEEK_CUR: realorigin = SEEK_CUR; break;
+ case SQ_SEEK_END: realorigin = SEEK_END; break;
+ case SQ_SEEK_SET: realorigin = SEEK_SET; break;
+ default: return -1; //failed
+ }
+ return fseek((FILE *)file,(long)offset,(int)realorigin);
+}
+
+SQInteger sqstd_ftell(SQFILE file)
+{
+ return ftell((FILE *)file);
+}
+
+SQInteger sqstd_fflush(SQFILE file)
+{
+ return fflush((FILE *)file);
+}
+
+SQInteger sqstd_fclose(SQFILE file)
+{
+ return fclose((FILE *)file);
+}
+
+SQInteger sqstd_feof(SQFILE file)
+{
+ return feof((FILE *)file);
+}
+
+//File
+struct SQFile : public SQStream {
+ SQFile() { _handle = NULL; _owns = false;}
+ SQFile(SQFILE file, bool owns) { _handle = file; _owns = owns;}
+ virtual ~SQFile() { Close(); }
+ bool Open(const SQChar *filename ,const SQChar *mode) {
+ Close();
+ if( (_handle = sqstd_fopen(filename,mode)) ) {
+ _owns = true;
+ return true;
+ }
+ return false;
+ }
+ void Close() {
+ if(_handle && _owns) {
+ sqstd_fclose(_handle);
+ _handle = NULL;
+ _owns = false;
+ }
+ }
+ SQInteger Read(void *buffer,SQInteger size) {
+ return sqstd_fread(buffer,1,size,_handle);
+ }
+ SQInteger Write(void *buffer,SQInteger size) {
+ return sqstd_fwrite(buffer,1,size,_handle);
+ }
+ SQInteger Flush() {
+ return sqstd_fflush(_handle);
+ }
+ SQInteger Tell() {
+ return sqstd_ftell(_handle);
+ }
+ SQInteger Len() {
+ SQInteger prevpos=Tell();
+ Seek(0,SQ_SEEK_END);
+ SQInteger size=Tell();
+ Seek(prevpos,SQ_SEEK_SET);
+ return size;
+ }
+ SQInteger Seek(SQInteger offset, SQInteger origin) {
+ return sqstd_fseek(_handle,offset,origin);
+ }
+ bool IsValid() { return _handle?true:false; }
+ bool EOS() { return Tell()==Len()?true:false;}
+ SQFILE GetHandle() {return _handle;}
+private:
+ SQFILE _handle;
+ bool _owns;
+};
+
+static SQInteger _file__typeof(HSQUIRRELVM v)
+{
+ sq_pushstring(v,_SC("file"),-1);
+ return 1;
+}
+
+static SQInteger _file_releasehook(SQUserPointer p, SQInteger size)
+{
+ SQFile *self = (SQFile*)p;
+ delete self;
+ return 1;
+}
+
+static SQInteger _file_constructor(HSQUIRRELVM v)
+{
+ const SQChar *filename,*mode;
+ bool owns = true;
+ SQFile *f;
+ SQFILE newf;
+ if(sq_gettype(v,2) == OT_STRING && sq_gettype(v,3) == OT_STRING) {
+ sq_getstring(v, 2, &filename);
+ sq_getstring(v, 3, &mode);
+ newf = sqstd_fopen(filename, mode);
+ if(!newf) return sq_throwerror(v, _SC("cannot open file"));
+ } else if(sq_gettype(v,2) == OT_USERPOINTER) {
+ owns = !(sq_gettype(v,3) == OT_NULL);
+ sq_getuserpointer(v,2,&newf);
+ } else {
+ return sq_throwerror(v,_SC("wrong parameter"));
+ }
+ f = new SQFile(newf,owns);
+ if(SQ_FAILED(sq_setinstanceup(v,1,f))) {
+ delete f;
+ return sq_throwerror(v, _SC("cannot create blob with negative size"));
+ }
+ sq_setreleasehook(v,1,_file_releasehook);
+ return 0;
+}
+
+//bindings
+#define _DECL_FILE_FUNC(name,nparams,typecheck) {_SC(#name),_file_##name,nparams,typecheck}
+static SQRegFunction _file_methods[] = {
+ _DECL_FILE_FUNC(constructor,3,_SC("x")),
+ _DECL_FILE_FUNC(_typeof,1,_SC("x")),
+ {0,0,0,0},
+};
+
+
+
+SQRESULT sqstd_createfile(HSQUIRRELVM v, SQFILE file,SQBool own)
+{
+ SQInteger top = sq_gettop(v);
+ sq_pushregistrytable(v);
+ sq_pushstring(v,_SC("std_file"),-1);
+ if(SQ_SUCCEEDED(sq_get(v,-2))) {
+ sq_remove(v,-2); //removes the registry
+ sq_pushroottable(v); // push the this
+ sq_pushuserpointer(v,file); //file
+ if(own){
+ sq_pushinteger(v,1); //true
+ }
+ else{
+ sq_pushnull(v); //false
+ }
+ if(SQ_SUCCEEDED( sq_call(v,3,SQTrue,SQFalse) )) {
+ sq_remove(v,-2);
+ return SQ_OK;
+ }
+ }
+ sq_settop(v,top);
+ return SQ_OK;
+}
+
+SQRESULT sqstd_getfile(HSQUIRRELVM v, SQInteger idx, SQFILE *file)
+{
+ SQFile *fileobj = NULL;
+ if(SQ_SUCCEEDED(sq_getinstanceup(v,idx,(SQUserPointer*)&fileobj,(SQUserPointer)SQSTD_FILE_TYPE_TAG))) {
+ *file = fileobj->GetHandle();
+ return SQ_OK;
+ }
+ return sq_throwerror(v,_SC("not a file"));
+}
+
+
+
+static SQInteger _io_file_lexfeed_ASCII(SQUserPointer file)
+{
+ SQInteger ret;
+ char c;
+ if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) )
+ return c;
+ return 0;
+}
+
+static SQInteger _io_file_lexfeed_UTF8(SQUserPointer file)
+{
+#define READ() \
+ if(sqstd_fread(&inchar,sizeof(inchar),1,(FILE *)file) != 1) \
+ return 0;
+
+ static const SQInteger utf8_lengths[16] =
+ {
+ 1,1,1,1,1,1,1,1, /* 0000 to 0111 : 1 byte (plain ASCII) */
+ 0,0,0,0, /* 1000 to 1011 : not valid */
+ 2,2, /* 1100, 1101 : 2 bytes */
+ 3, /* 1110 : 3 bytes */
+ 4 /* 1111 :4 bytes */
+ };
+ static unsigned char byte_masks[5] = {0,0,0x1f,0x0f,0x07};
+ unsigned char inchar;
+ SQInteger c = 0;
+ READ();
+ c = inchar;
+ //
+ if(c >= 0x80) {
+ SQInteger tmp;
+ SQInteger codelen = utf8_lengths[c>>4];
+ if(codelen == 0)
+ return 0;
+ //"invalid UTF-8 stream";
+ tmp = c&byte_masks[codelen];
+ for(SQInteger n = 0; n < codelen-1; n++) {
+ tmp<<=6;
+ READ();
+ tmp |= inchar & 0x3F;
+ }
+ c = tmp;
+ }
+ return c;
+}
+
+static SQInteger _io_file_lexfeed_UCS2_LE(SQUserPointer file)
+{
+ SQInteger ret;
+ wchar_t c;
+ if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) )
+ return (SQChar)c;
+ return 0;
+}
+
+static SQInteger _io_file_lexfeed_UCS2_BE(SQUserPointer file)
+{
+ SQInteger ret;
+ unsigned short c;
+ if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) ) {
+ c = ((c>>8)&0x00FF)| ((c<<8)&0xFF00);
+ return (SQChar)c;
+ }
+ return 0;
+}
+
+SQInteger file_read(SQUserPointer file,SQUserPointer buf,SQInteger size)
+{
+ SQInteger ret;
+ if( ( ret = sqstd_fread(buf,1,size,(SQFILE)file ))!=0 )return ret;
+ return -1;
+}
+
+SQInteger file_write(SQUserPointer file,SQUserPointer p,SQInteger size)
+{
+ return sqstd_fwrite(p,1,size,(SQFILE)file);
+}
+
+SQRESULT sqstd_loadfile(HSQUIRRELVM v,const SQChar *filename,SQBool printerror)
+{
+ SQFILE file = sqstd_fopen(filename,_SC("rb"));
+ SQInteger ret;
+ unsigned short us;
+ unsigned char uc;
+ SQLEXREADFUNC func = _io_file_lexfeed_ASCII;
+ if(file){
+ ret = sqstd_fread(&us,1,2,file);
+ if(ret != 2) {
+ //probably an empty file
+ us = 0;
+ }
+ if(us == SQ_BYTECODE_STREAM_TAG) { //BYTECODE
+ sqstd_fseek(file,0,SQ_SEEK_SET);
+ if(SQ_SUCCEEDED(sq_readclosure(v,file_read,file))) {
+ sqstd_fclose(file);
+ return SQ_OK;
+ }
+ }
+ else { //SCRIPT
+ switch(us)
+ {
+ //gotta swap the next 2 lines on BIG endian machines
+ case 0xFFFE: func = _io_file_lexfeed_UCS2_BE; break;//UTF-16 little endian;
+ case 0xFEFF: func = _io_file_lexfeed_UCS2_LE; break;//UTF-16 big endian;
+ case 0xBBEF:
+ if(sqstd_fread(&uc,1,sizeof(uc),file) == 0) {
+ sqstd_fclose(file);
+ return sq_throwerror(v,_SC("io error"));
+ }
+ if(uc != 0xBF) {
+ sqstd_fclose(file);
+ return sq_throwerror(v,_SC("Unrecognozed ecoding"));
+ }
+ func = _io_file_lexfeed_UTF8;
+ break;//UTF-8 ;
+ default: sqstd_fseek(file,0,SQ_SEEK_SET); break; // ascii
+ }
+
+ if(SQ_SUCCEEDED(sq_compile(v,func,file,filename,printerror))){
+ sqstd_fclose(file);
+ return SQ_OK;
+ }
+ }
+ sqstd_fclose(file);
+ return SQ_ERROR;
+ }
+ return sq_throwerror(v,_SC("cannot open the file"));
+}
+
+SQRESULT sqstd_dofile(HSQUIRRELVM v,const SQChar *filename,SQBool retval,SQBool printerror)
+{
+ if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror))) {
+ sq_push(v,-2);
+ if(SQ_SUCCEEDED(sq_call(v,1,retval,SQTrue))) {
+ sq_remove(v,retval?-2:-1); //removes the closure
+ return 1;
+ }
+ sq_pop(v,1); //removes the closure
+ }
+ return SQ_ERROR;
+}
+
+SQRESULT sqstd_writeclosuretofile(HSQUIRRELVM v,const SQChar *filename)
+{
+ SQFILE file = sqstd_fopen(filename,_SC("wb+"));
+ if(!file) return sq_throwerror(v,_SC("cannot open the file"));
+ if(SQ_SUCCEEDED(sq_writeclosure(v,file_write,file))) {
+ sqstd_fclose(file);
+ return SQ_OK;
+ }
+ sqstd_fclose(file);
+ return SQ_ERROR; //forward the error
+}
+
+SQInteger _g_io_loadfile(HSQUIRRELVM v)
+{
+ const SQChar *filename;
+ SQBool printerror = SQFalse;
+ sq_getstring(v,2,&filename);
+ if(sq_gettop(v) >= 3) {
+ sq_getbool(v,3,&printerror);
+ }
+ if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror)))
+ return 1;
+ return SQ_ERROR; //propagates the error
+}
+
+SQInteger _g_io_writeclosuretofile(HSQUIRRELVM v)
+{
+ const SQChar *filename;
+ sq_getstring(v,2,&filename);
+ if(SQ_SUCCEEDED(sqstd_writeclosuretofile(v,filename)))
+ return 1;
+ return SQ_ERROR; //propagates the error
+}
+
+SQInteger _g_io_dofile(HSQUIRRELVM v)
+{
+ const SQChar *filename;
+ SQBool printerror = SQFalse;
+ sq_getstring(v,2,&filename);
+ if(sq_gettop(v) >= 3) {
+ sq_getbool(v,3,&printerror);
+ }
+ sq_push(v,1); //repush the this
+ if(SQ_SUCCEEDED(sqstd_dofile(v,filename,SQTrue,printerror)))
+ return 1;
+ return SQ_ERROR; //propagates the error
+}
+
+#define _DECL_GLOBALIO_FUNC(name,nparams,typecheck) {_SC(#name),_g_io_##name,nparams,typecheck}
+static SQRegFunction iolib_funcs[]={
+ _DECL_GLOBALIO_FUNC(loadfile,-2,_SC(".sb")),
+ _DECL_GLOBALIO_FUNC(dofile,-2,_SC(".sb")),
+ _DECL_GLOBALIO_FUNC(writeclosuretofile,3,_SC(".sc")),
+ {0,0}
+};
+
+SQRESULT sqstd_register_iolib(HSQUIRRELVM v)
+{
+ SQInteger top = sq_gettop(v);
+ //create delegate
+ declare_stream(v,_SC("file"),(SQUserPointer)SQSTD_FILE_TYPE_TAG,_SC("std_file"),_file_methods,iolib_funcs);
+ sq_pushstring(v,_SC("stdout"),-1);
+ sqstd_createfile(v,stdout,SQFalse);
+ sq_createslot(v,-3);
+ sq_pushstring(v,_SC("stdin"),-1);
+ sqstd_createfile(v,stdin,SQFalse);
+ sq_createslot(v,-3);
+ sq_pushstring(v,_SC("stderr"),-1);
+ sqstd_createfile(v,stderr,SQFalse);
+ sq_createslot(v,-3);
+ sq_settop(v,top);
+ return SQ_OK;
+}
--- /dev/null
+/* see copyright notice in squirrel.h */
+#include <squirrel.h>
+#include <math.h>
+#include <stdlib.h>
+#include <sqstdmath.h>
+
+#define SINGLE_ARG_FUNC(_funcname) static SQInteger math_##_funcname(HSQUIRRELVM v){ \
+ SQFloat f; \
+ sq_getfloat(v,2,&f); \
+ sq_pushfloat(v,(SQFloat)_funcname(f)); \
+ return 1; \
+}
+
+#define TWO_ARGS_FUNC(_funcname) static SQInteger math_##_funcname(HSQUIRRELVM v){ \
+ SQFloat p1,p2; \
+ sq_getfloat(v,2,&p1); \
+ sq_getfloat(v,3,&p2); \
+ sq_pushfloat(v,(SQFloat)_funcname(p1,p2)); \
+ return 1; \
+}
+
+static SQInteger math_srand(HSQUIRRELVM v)
+{
+ SQInteger i;
+ if(SQ_FAILED(sq_getinteger(v,2,&i)))
+ return sq_throwerror(v,_SC("invalid param"));
+ srand((unsigned int)i);
+ return 0;
+}
+
+static SQInteger math_rand(HSQUIRRELVM v)
+{
+ sq_pushinteger(v,rand());
+ return 1;
+}
+
+static SQInteger math_abs(HSQUIRRELVM v)
+{
+ SQInteger n;
+ sq_getinteger(v,2,&n);
+ sq_pushinteger(v,(SQInteger)abs((int)n));
+ return 1;
+}
+
+SINGLE_ARG_FUNC(sqrt)
+SINGLE_ARG_FUNC(fabs)
+SINGLE_ARG_FUNC(sin)
+SINGLE_ARG_FUNC(cos)
+SINGLE_ARG_FUNC(asin)
+SINGLE_ARG_FUNC(acos)
+SINGLE_ARG_FUNC(log)
+SINGLE_ARG_FUNC(log10)
+SINGLE_ARG_FUNC(tan)
+SINGLE_ARG_FUNC(atan)
+TWO_ARGS_FUNC(atan2)
+TWO_ARGS_FUNC(pow)
+SINGLE_ARG_FUNC(floor)
+SINGLE_ARG_FUNC(ceil)
+SINGLE_ARG_FUNC(exp)
+
+#define _DECL_FUNC(name,nparams,tycheck) {_SC(#name),math_##name,nparams,tycheck}
+static SQRegFunction mathlib_funcs[] = {
+ _DECL_FUNC(sqrt,2,_SC(".n")),
+ _DECL_FUNC(sin,2,_SC(".n")),
+ _DECL_FUNC(cos,2,_SC(".n")),
+ _DECL_FUNC(asin,2,_SC(".n")),
+ _DECL_FUNC(acos,2,_SC(".n")),
+ _DECL_FUNC(log,2,_SC(".n")),
+ _DECL_FUNC(log10,2,_SC(".n")),
+ _DECL_FUNC(tan,2,_SC(".n")),
+ _DECL_FUNC(atan,2,_SC(".n")),
+ _DECL_FUNC(atan2,3,_SC(".nn")),
+ _DECL_FUNC(pow,3,_SC(".nn")),
+ _DECL_FUNC(floor,2,_SC(".n")),
+ _DECL_FUNC(ceil,2,_SC(".n")),
+ _DECL_FUNC(exp,2,_SC(".n")),
+ _DECL_FUNC(srand,2,_SC(".n")),
+ _DECL_FUNC(rand,1,NULL),
+ _DECL_FUNC(fabs,2,_SC(".n")),
+ _DECL_FUNC(abs,2,_SC(".n")),
+ {0,0},
+};
+
+#ifndef M_PI
+#define M_PI (3.14159265358979323846)
+#endif
+
+SQRESULT sqstd_register_mathlib(HSQUIRRELVM v)
+{
+ SQInteger i=0;
+ while(mathlib_funcs[i].name!=0) {
+ sq_pushstring(v,mathlib_funcs[i].name,-1);
+ sq_newclosure(v,mathlib_funcs[i].f,0);
+ sq_setparamscheck(v,mathlib_funcs[i].nparamscheck,mathlib_funcs[i].typemask);
+ sq_setnativeclosurename(v,-1,mathlib_funcs[i].name);
+ sq_createslot(v,-3);
+ i++;
+ }
+ sq_pushstring(v,_SC("RAND_MAX"),-1);
+ sq_pushinteger(v,RAND_MAX);
+ sq_createslot(v,-3);
+ sq_pushstring(v,_SC("PI"),-1);
+ sq_pushfloat(v,(SQFloat)M_PI);
+ sq_createslot(v,-3);
+ return SQ_OK;
+}
--- /dev/null
+/* see copyright notice in squirrel.h */
+#include <squirrel.h>
+#include <string.h>
+#include <ctype.h>
+#include <setjmp.h>
+#include "sqstdstring.h"
+
+#ifdef _UINCODE
+#define scisprint iswprint
+#else
+#define scisprint isprint
+#endif
+
+#ifdef _DEBUG
+#include <stdio.h>
+
+static const SQChar *g_nnames[] =
+{
+ _SC("NONE"),_SC("OP_GREEDY"), _SC("OP_OR"),
+ _SC("OP_EXPR"),_SC("OP_NOCAPEXPR"),_SC("OP_DOT"), _SC("OP_CLASS"),
+ _SC("OP_CCLASS"),_SC("OP_NCLASS"),_SC("OP_RANGE"),_SC("OP_CHAR"),
+ _SC("OP_EOL"),_SC("OP_BOL"),_SC("OP_WB")
+};
+
+#endif
+
+#define OP_GREEDY (MAX_CHAR+1) // * + ? {n}
+#define OP_OR (MAX_CHAR+2)
+#define OP_EXPR (MAX_CHAR+3) //parentesis ()
+#define OP_NOCAPEXPR (MAX_CHAR+4) //parentesis (?:)
+#define OP_DOT (MAX_CHAR+5)
+#define OP_CLASS (MAX_CHAR+6)
+#define OP_CCLASS (MAX_CHAR+7)
+#define OP_NCLASS (MAX_CHAR+8) //negates class the [^
+#define OP_RANGE (MAX_CHAR+9)
+#define OP_CHAR (MAX_CHAR+10)
+#define OP_EOL (MAX_CHAR+11)
+#define OP_BOL (MAX_CHAR+12)
+#define OP_WB (MAX_CHAR+13)
+
+#define SQREX_SYMBOL_ANY_CHAR ('.')
+#define SQREX_SYMBOL_GREEDY_ONE_OR_MORE ('+')
+#define SQREX_SYMBOL_GREEDY_ZERO_OR_MORE ('*')
+#define SQREX_SYMBOL_GREEDY_ZERO_OR_ONE ('?')
+#define SQREX_SYMBOL_BRANCH ('|')
+#define SQREX_SYMBOL_END_OF_STRING ('$')
+#define SQREX_SYMBOL_BEGINNING_OF_STRING ('^')
+#define SQREX_SYMBOL_ESCAPE_CHAR ('\\')
+
+
+typedef int SQRexNodeType;
+
+typedef struct tagSQRexNode{
+ SQRexNodeType type;
+ SQInteger left;
+ SQInteger right;
+ SQInteger next;
+}SQRexNode;
+
+struct SQRex{
+ const SQChar *_eol;
+ const SQChar *_bol;
+ const SQChar *_p;
+ SQInteger _first;
+ SQInteger _op;
+ SQRexNode *_nodes;
+ SQInteger _nallocated;
+ SQInteger _nsize;
+ SQInteger _nsubexpr;
+ SQRexMatch *_matches;
+ SQInteger _currsubexp;
+ void *_jmpbuf;
+ const SQChar **_error;
+};
+
+static SQInteger sqstd_rex_list(SQRex *exp);
+
+static SQInteger sqstd_rex_newnode(SQRex *exp, SQRexNodeType type)
+{
+ SQRexNode n;
+ n.type = type;
+ n.next = n.right = n.left = -1;
+ if(type == OP_EXPR)
+ n.right = exp->_nsubexpr++;
+ if(exp->_nallocated < (exp->_nsize + 1)) {
+ SQInteger oldsize = exp->_nallocated;
+ exp->_nallocated *= 2;
+ exp->_nodes = (SQRexNode *)sq_realloc(exp->_nodes, oldsize * sizeof(SQRexNode) ,exp->_nallocated * sizeof(SQRexNode));
+ }
+ exp->_nodes[exp->_nsize++] = n;
+ SQInteger newid = exp->_nsize - 1;
+ return (SQInteger)newid;
+}
+
+static void sqstd_rex_error(SQRex *exp,const SQChar *error)
+{
+ if(exp->_error) *exp->_error = error;
+ longjmp(*((jmp_buf*)exp->_jmpbuf),-1);
+}
+
+static void sqstd_rex_expect(SQRex *exp, SQInteger n){
+ if((*exp->_p) != n)
+ sqstd_rex_error(exp, _SC("expected paren"));
+ exp->_p++;
+}
+
+static SQChar sqstd_rex_escapechar(SQRex *exp)
+{
+ if(*exp->_p == SQREX_SYMBOL_ESCAPE_CHAR){
+ exp->_p++;
+ switch(*exp->_p) {
+ case 'v': exp->_p++; return '\v';
+ case 'n': exp->_p++; return '\n';
+ case 't': exp->_p++; return '\t';
+ case 'r': exp->_p++; return '\r';
+ case 'f': exp->_p++; return '\f';
+ default: return (*exp->_p++);
+ }
+ } else if(!scisprint(*exp->_p)) sqstd_rex_error(exp,_SC("letter expected"));
+ return (*exp->_p++);
+}
+
+static SQInteger sqstd_rex_charclass(SQRex *exp,SQInteger classid)
+{
+ SQInteger n = sqstd_rex_newnode(exp,OP_CCLASS);
+ exp->_nodes[n].left = classid;
+ return n;
+}
+
+static SQInteger sqstd_rex_charnode(SQRex *exp,SQBool isclass)
+{
+ SQChar t;
+ if(*exp->_p == SQREX_SYMBOL_ESCAPE_CHAR) {
+ exp->_p++;
+ switch(*exp->_p) {
+ case 'n': exp->_p++; return sqstd_rex_newnode(exp,'\n');
+ case 't': exp->_p++; return sqstd_rex_newnode(exp,'\t');
+ case 'r': exp->_p++; return sqstd_rex_newnode(exp,'\r');
+ case 'f': exp->_p++; return sqstd_rex_newnode(exp,'\f');
+ case 'v': exp->_p++; return sqstd_rex_newnode(exp,'\v');
+ case 'a': case 'A': case 'w': case 'W': case 's': case 'S':
+ case 'd': case 'D': case 'x': case 'X': case 'c': case 'C':
+ case 'p': case 'P': case 'l': case 'u':
+ {
+ t = *exp->_p; exp->_p++;
+ return sqstd_rex_charclass(exp,t);
+ }
+ case 'b':
+ case 'B':
+ if(!isclass) {
+ SQInteger node = sqstd_rex_newnode(exp,OP_WB);
+ exp->_nodes[node].left = *exp->_p;
+ exp->_p++;
+ return node;
+ } //else default
+ default:
+ t = *exp->_p; exp->_p++;
+ return sqstd_rex_newnode(exp,t);
+ }
+ }
+ else if(!scisprint(*exp->_p)) {
+
+ sqstd_rex_error(exp,_SC("letter expected"));
+ }
+ t = *exp->_p; exp->_p++;
+ return sqstd_rex_newnode(exp,t);
+}
+static SQInteger sqstd_rex_class(SQRex *exp)
+{
+ SQInteger ret = -1;
+ SQInteger first = -1,chain;
+ if(*exp->_p == SQREX_SYMBOL_BEGINNING_OF_STRING){
+ ret = sqstd_rex_newnode(exp,OP_NCLASS);
+ exp->_p++;
+ }else ret = sqstd_rex_newnode(exp,OP_CLASS);
+
+ if(*exp->_p == ']') sqstd_rex_error(exp,_SC("empty class"));
+ chain = ret;
+ while(*exp->_p != ']' && exp->_p != exp->_eol) {
+ if(*exp->_p == '-' && first != -1){
+ SQInteger r;
+ if(*exp->_p++ == ']') sqstd_rex_error(exp,_SC("unfinished range"));
+ r = sqstd_rex_newnode(exp,OP_RANGE);
+ if(first>*exp->_p) sqstd_rex_error(exp,_SC("invalid range"));
+ if(exp->_nodes[first].type == OP_CCLASS) sqstd_rex_error(exp,_SC("cannot use character classes in ranges"));
+ exp->_nodes[r].left = exp->_nodes[first].type;
+ SQInteger t = sqstd_rex_escapechar(exp);
+ exp->_nodes[r].right = t;
+ exp->_nodes[chain].next = r;
+ chain = r;
+ first = -1;
+ }
+ else{
+ if(first!=-1){
+ SQInteger c = first;
+ exp->_nodes[chain].next = c;
+ chain = c;
+ first = sqstd_rex_charnode(exp,SQTrue);
+ }
+ else{
+ first = sqstd_rex_charnode(exp,SQTrue);
+ }
+ }
+ }
+ if(first!=-1){
+ SQInteger c = first;
+ exp->_nodes[chain].next = c;
+ chain = c;
+ first = -1;
+ }
+ /* hack? */
+ exp->_nodes[ret].left = exp->_nodes[ret].next;
+ exp->_nodes[ret].next = -1;
+ return ret;
+}
+
+static SQInteger sqstd_rex_parsenumber(SQRex *exp)
+{
+ SQInteger ret = *exp->_p-'0';
+ SQInteger positions = 10;
+ exp->_p++;
+ while(isdigit(*exp->_p)) {
+ ret = ret*10+(*exp->_p++-'0');
+ if(positions==1000000000) sqstd_rex_error(exp,_SC("overflow in numeric constant"));
+ positions *= 10;
+ };
+ return ret;
+}
+
+static SQInteger sqstd_rex_element(SQRex *exp)
+{
+ SQInteger ret = -1;
+ switch(*exp->_p)
+ {
+ case '(': {
+ SQInteger expr;
+ exp->_p++;
+
+
+ if(*exp->_p =='?') {
+ exp->_p++;
+ sqstd_rex_expect(exp,':');
+ expr = sqstd_rex_newnode(exp,OP_NOCAPEXPR);
+ }
+ else
+ expr = sqstd_rex_newnode(exp,OP_EXPR);
+ SQInteger newn = sqstd_rex_list(exp);
+ exp->_nodes[expr].left = newn;
+ ret = expr;
+ sqstd_rex_expect(exp,')');
+ }
+ break;
+ case '[':
+ exp->_p++;
+ ret = sqstd_rex_class(exp);
+ sqstd_rex_expect(exp,']');
+ break;
+ case SQREX_SYMBOL_END_OF_STRING: exp->_p++; ret = sqstd_rex_newnode(exp,OP_EOL);break;
+ case SQREX_SYMBOL_ANY_CHAR: exp->_p++; ret = sqstd_rex_newnode(exp,OP_DOT);break;
+ default:
+ ret = sqstd_rex_charnode(exp,SQFalse);
+ break;
+ }
+
+
+ SQInteger op;
+ SQBool isgreedy = SQFalse;
+ unsigned short p0 = 0, p1 = 0;
+ switch(*exp->_p){
+ case SQREX_SYMBOL_GREEDY_ZERO_OR_MORE: p0 = 0; p1 = 0xFFFF; exp->_p++; isgreedy = SQTrue; break;
+ case SQREX_SYMBOL_GREEDY_ONE_OR_MORE: p0 = 1; p1 = 0xFFFF; exp->_p++; isgreedy = SQTrue; break;
+ case SQREX_SYMBOL_GREEDY_ZERO_OR_ONE: p0 = 0; p1 = 1; exp->_p++; isgreedy = SQTrue; break;
+ case '{':
+ exp->_p++;
+ if(!isdigit(*exp->_p)) sqstd_rex_error(exp,_SC("number expected"));
+ p0 = (unsigned short)sqstd_rex_parsenumber(exp);
+ /*******************************/
+ switch(*exp->_p) {
+ case '}':
+ p1 = p0; exp->_p++;
+ break;
+ case ',':
+ exp->_p++;
+ p1 = 0xFFFF;
+ if(isdigit(*exp->_p)){
+ p1 = (unsigned short)sqstd_rex_parsenumber(exp);
+ }
+ sqstd_rex_expect(exp,'}');
+ break;
+ default:
+ sqstd_rex_error(exp,_SC(", or } expected"));
+ }
+ /*******************************/
+ isgreedy = SQTrue;
+ break;
+
+ }
+ if(isgreedy) {
+ SQInteger nnode = sqstd_rex_newnode(exp,OP_GREEDY);
+ op = OP_GREEDY;
+ exp->_nodes[nnode].left = ret;
+ exp->_nodes[nnode].right = ((p0)<<16)|p1;
+ ret = nnode;
+ }
+
+ if((*exp->_p != SQREX_SYMBOL_BRANCH) && (*exp->_p != ')') && (*exp->_p != SQREX_SYMBOL_GREEDY_ZERO_OR_MORE) && (*exp->_p != SQREX_SYMBOL_GREEDY_ONE_OR_MORE) && (*exp->_p != '\0')) {
+ SQInteger nnode = sqstd_rex_element(exp);
+ exp->_nodes[ret].next = nnode;
+ }
+
+ return ret;
+}
+
+static SQInteger sqstd_rex_list(SQRex *exp)
+{
+ SQInteger ret=-1,e;
+ if(*exp->_p == SQREX_SYMBOL_BEGINNING_OF_STRING) {
+ exp->_p++;
+ ret = sqstd_rex_newnode(exp,OP_BOL);
+ }
+ e = sqstd_rex_element(exp);
+ if(ret != -1) {
+ exp->_nodes[ret].next = e;
+ }
+ else ret = e;
+
+ if(*exp->_p == SQREX_SYMBOL_BRANCH) {
+ SQInteger temp,tright;
+ exp->_p++;
+ temp = sqstd_rex_newnode(exp,OP_OR);
+ exp->_nodes[temp].left = ret;
+ tright = sqstd_rex_list(exp);
+ exp->_nodes[temp].right = tright;
+ ret = temp;
+ }
+ return ret;
+}
+
+static SQBool sqstd_rex_matchcclass(SQInteger cclass,SQChar c)
+{
+ switch(cclass) {
+ case 'a': return isalpha(c)?SQTrue:SQFalse;
+ case 'A': return !isalpha(c)?SQTrue:SQFalse;
+ case 'w': return (isalnum(c) || c == '_')?SQTrue:SQFalse;
+ case 'W': return (!isalnum(c) && c != '_')?SQTrue:SQFalse;
+ case 's': return isspace(c)?SQTrue:SQFalse;
+ case 'S': return !isspace(c)?SQTrue:SQFalse;
+ case 'd': return isdigit(c)?SQTrue:SQFalse;
+ case 'D': return !isdigit(c)?SQTrue:SQFalse;
+ case 'x': return isxdigit(c)?SQTrue:SQFalse;
+ case 'X': return !isxdigit(c)?SQTrue:SQFalse;
+ case 'c': return iscntrl(c)?SQTrue:SQFalse;
+ case 'C': return !iscntrl(c)?SQTrue:SQFalse;
+ case 'p': return ispunct(c)?SQTrue:SQFalse;
+ case 'P': return !ispunct(c)?SQTrue:SQFalse;
+ case 'l': return islower(c)?SQTrue:SQFalse;
+ case 'u': return isupper(c)?SQTrue:SQFalse;
+ }
+ return SQFalse; /*cannot happen*/
+}
+
+static SQBool sqstd_rex_matchclass(SQRex* exp,SQRexNode *node,SQChar c)
+{
+ do {
+ switch(node->type) {
+ case OP_RANGE:
+ if(c >= node->left && c <= node->right) return SQTrue;
+ break;
+ case OP_CCLASS:
+ if(sqstd_rex_matchcclass(node->left,c)) return SQTrue;
+ break;
+ default:
+ if(c == node->type)return SQTrue;
+ }
+ } while((node->next != -1) && (node = &exp->_nodes[node->next]));
+ return SQFalse;
+}
+
+static const SQChar *sqstd_rex_matchnode(SQRex* exp,SQRexNode *node,const SQChar *str,SQRexNode *next)
+{
+
+ SQRexNodeType type = node->type;
+ switch(type) {
+ case OP_GREEDY: {
+ //SQRexNode *greedystop = (node->next != -1) ? &exp->_nodes[node->next] : NULL;
+ SQRexNode *greedystop = NULL;
+ SQInteger p0 = (node->right >> 16)&0x0000FFFF, p1 = node->right&0x0000FFFF, nmaches = 0;
+ const SQChar *s=str, *good = str;
+
+ if(node->next != -1) {
+ greedystop = &exp->_nodes[node->next];
+ }
+ else {
+ greedystop = next;
+ }
+
+ while((nmaches == 0xFFFF || nmaches < p1)) {
+
+ const SQChar *stop;
+ if(!(s = sqstd_rex_matchnode(exp,&exp->_nodes[node->left],s,greedystop)))
+ break;
+ nmaches++;
+ good=s;
+ if(greedystop) {
+ //checks that 0 matches satisfy the expression(if so skips)
+ //if not would always stop(for instance if is a '?')
+ if(greedystop->type != OP_GREEDY ||
+ (greedystop->type == OP_GREEDY && ((greedystop->right >> 16)&0x0000FFFF) != 0))
+ {
+ SQRexNode *gnext = NULL;
+ if(greedystop->next != -1) {
+ gnext = &exp->_nodes[greedystop->next];
+ }else if(next && next->next != -1){
+ gnext = &exp->_nodes[next->next];
+ }
+ stop = sqstd_rex_matchnode(exp,greedystop,s,gnext);
+ if(stop) {
+ //if satisfied stop it
+ if(p0 == p1 && p0 == nmaches) break;
+ else if(nmaches >= p0 && p1 == 0xFFFF) break;
+ else if(nmaches >= p0 && nmaches <= p1) break;
+ }
+ }
+ }
+
+ if(s >= exp->_eol)
+ break;
+ }
+ if(p0 == p1 && p0 == nmaches) return good;
+ else if(nmaches >= p0 && p1 == 0xFFFF) return good;
+ else if(nmaches >= p0 && nmaches <= p1) return good;
+ return NULL;
+ }
+ case OP_OR: {
+ const SQChar *asd = str;
+ SQRexNode *temp=&exp->_nodes[node->left];
+ while( (asd = sqstd_rex_matchnode(exp,temp,asd,NULL)) ) {
+ if(temp->next != -1)
+ temp = &exp->_nodes[temp->next];
+ else
+ return asd;
+ }
+ asd = str;
+ temp = &exp->_nodes[node->right];
+ while( (asd = sqstd_rex_matchnode(exp,temp,asd,NULL)) ) {
+ if(temp->next != -1)
+ temp = &exp->_nodes[temp->next];
+ else
+ return asd;
+ }
+ return NULL;
+ break;
+ }
+ case OP_EXPR:
+ case OP_NOCAPEXPR:{
+ SQRexNode *n = &exp->_nodes[node->left];
+ const SQChar *cur = str;
+ SQInteger capture = -1;
+ if(node->type != OP_NOCAPEXPR && node->right == exp->_currsubexp) {
+ capture = exp->_currsubexp;
+ exp->_matches[capture].begin = cur;
+ exp->_currsubexp++;
+ }
+
+ do {
+ SQRexNode *subnext = NULL;
+ if(n->next != -1) {
+ subnext = &exp->_nodes[n->next];
+ }else {
+ subnext = next;
+ }
+ if(!(cur = sqstd_rex_matchnode(exp,n,cur,subnext))) {
+ if(capture != -1){
+ exp->_matches[capture].begin = 0;
+ exp->_matches[capture].len = 0;
+ }
+ return NULL;
+ }
+ } while((n->next != -1) && (n = &exp->_nodes[n->next]));
+
+ if(capture != -1)
+ exp->_matches[capture].len = cur - exp->_matches[capture].begin;
+ return cur;
+ }
+ case OP_WB:
+ if(str == exp->_bol && !isspace(*str)
+ || (str == exp->_eol && !isspace(*(str-1)))
+ || (!isspace(*str) && isspace(*(str+1)))
+ || (isspace(*str) && !isspace(*(str+1))) ) {
+ return (node->left == 'b')?str:NULL;
+ }
+ return (node->left == 'b')?NULL:str;
+ case OP_BOL:
+ if(str == exp->_bol) return str;
+ return NULL;
+ case OP_EOL:
+ if(str == exp->_eol) return str;
+ return NULL;
+ case OP_DOT:{
+ *str++;
+ }
+ return str;
+ case OP_NCLASS:
+ case OP_CLASS:
+ if(sqstd_rex_matchclass(exp,&exp->_nodes[node->left],*str)?(type == OP_CLASS?SQTrue:SQFalse):(type == OP_NCLASS?SQTrue:SQFalse)) {
+ *str++;
+ return str;
+ }
+ return NULL;
+ case OP_CCLASS:
+ if(sqstd_rex_matchcclass(node->left,*str)) {
+ *str++;
+ return str;
+ }
+ return NULL;
+ default: /* char */
+ if(*str != node->type) return NULL;
+ *str++;
+ return str;
+ }
+ return NULL;
+}
+
+/* public api */
+SQRex *sqstd_rex_compile(const SQChar *pattern,const SQChar **error)
+{
+ SQRex *exp = (SQRex *)sq_malloc(sizeof(SQRex));
+ exp->_eol = exp->_bol = NULL;
+ exp->_p = pattern;
+ exp->_nallocated = (SQInteger)scstrlen(pattern) * sizeof(SQChar);
+ exp->_nodes = (SQRexNode *)sq_malloc(exp->_nallocated * sizeof(SQRexNode));
+ exp->_nsize = 0;
+ exp->_matches = 0;
+ exp->_nsubexpr = 0;
+ exp->_first = sqstd_rex_newnode(exp,OP_EXPR);
+ exp->_error = error;
+ exp->_jmpbuf = sq_malloc(sizeof(jmp_buf));
+ if(setjmp(*((jmp_buf*)exp->_jmpbuf)) == 0) {
+ SQInteger res = sqstd_rex_list(exp);
+ exp->_nodes[exp->_first].left = res;
+ if(*exp->_p!='\0')
+ sqstd_rex_error(exp,_SC("unexpected character"));
+#ifdef _DEBUG
+ {
+ SQInteger nsize,i;
+ SQRexNode *t;
+ nsize = exp->_nsize;
+ t = &exp->_nodes[0];
+ scprintf(_SC("\n"));
+ for(i = 0;i < nsize; i++) {
+ if(exp->_nodes[i].type>MAX_CHAR)
+ scprintf(_SC("[%02d] %10s "),i,g_nnames[exp->_nodes[i].type-MAX_CHAR]);
+ else
+ scprintf(_SC("[%02d] %10c "),i,exp->_nodes[i].type);
+ scprintf(_SC("left %02d right %02d next %02d\n"),exp->_nodes[i].left,exp->_nodes[i].right,exp->_nodes[i].next);
+ }
+ scprintf(_SC("\n"));
+ }
+#endif
+ exp->_matches = (SQRexMatch *) sq_malloc(exp->_nsubexpr * sizeof(SQRexMatch));
+ memset(exp->_matches,0,exp->_nsubexpr * sizeof(SQRexMatch));
+ }
+ else{
+ sqstd_rex_free(exp);
+ return NULL;
+ }
+ return exp;
+}
+
+void sqstd_rex_free(SQRex *exp)
+{
+ if(exp) {
+ if(exp->_nodes) sq_free(exp->_nodes,exp->_nallocated * sizeof(SQRexNode));
+ if(exp->_jmpbuf) sq_free(exp->_jmpbuf,sizeof(jmp_buf));
+ if(exp->_matches) sq_free(exp->_matches,exp->_nsubexpr * sizeof(SQRexMatch));
+ sq_free(exp,sizeof(SQRex));
+ }
+}
+
+SQBool sqstd_rex_match(SQRex* exp,const SQChar* text)
+{
+ const SQChar* res = NULL;
+ exp->_bol = text;
+ exp->_eol = text + scstrlen(text);
+ exp->_currsubexp = 0;
+ res = sqstd_rex_matchnode(exp,exp->_nodes,text,NULL);
+ if(res == NULL || res != exp->_eol)
+ return SQFalse;
+ return SQTrue;
+}
+
+SQBool sqstd_rex_searchrange(SQRex* exp,const SQChar* text_begin,const SQChar* text_end,const SQChar** out_begin, const SQChar** out_end)
+{
+ const SQChar *cur = NULL;
+ SQInteger node = exp->_first;
+ if(text_begin >= text_end) return SQFalse;
+ exp->_bol = text_begin;
+ exp->_eol = text_end;
+ do {
+ cur = text_begin;
+ while(node != -1) {
+ exp->_currsubexp = 0;
+ cur = sqstd_rex_matchnode(exp,&exp->_nodes[node],cur,NULL);
+ if(!cur)
+ break;
+ node = exp->_nodes[node].next;
+ }
+ *text_begin++;
+ } while(cur == NULL && text_begin != text_end);
+
+ if(cur == NULL)
+ return SQFalse;
+
+ --text_begin;
+
+ if(out_begin) *out_begin = text_begin;
+ if(out_end) *out_end = cur;
+ return SQTrue;
+}
+
+SQBool sqstd_rex_search(SQRex* exp,const SQChar* text, const SQChar** out_begin, const SQChar** out_end)
+{
+ return sqstd_rex_searchrange(exp,text,text + scstrlen(text),out_begin,out_end);
+}
+
+SQInteger sqstd_rex_getsubexpcount(SQRex* exp)
+{
+ return exp->_nsubexpr;
+}
+
+SQBool sqstd_rex_getsubexp(SQRex* exp, SQInteger n, SQRexMatch *subexp)
+{
+ if( n<0 || n >= exp->_nsubexpr) return SQFalse;
+ *subexp = exp->_matches[n];
+ return SQTrue;
+}
+
--- /dev/null
+/* see copyright notice in squirrel.h */
+#include <new>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <squirrel.h>
+#include <sqstdio.h>
+#include <sqstdblob.h>
+#include "sqstdstream.h"
+#include "sqstdblobimpl.h"
+
+#define SETUP_STREAM(v) \
+ SQStream *self = NULL; \
+ if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_STREAM_TYPE_TAG))) \
+ return sq_throwerror(v,_SC("invalid type tag")); \
+ if(!self->IsValid()) \
+ return sq_throwerror(v,_SC("the stream is invalid"));
+
+SQInteger _stream_readblob(HSQUIRRELVM v)
+{
+ SETUP_STREAM(v);
+ SQUserPointer data,blobp;
+ SQInteger size,res;
+ sq_getinteger(v,2,&size);
+ if(size > self->Len()) {
+ size = self->Len();
+ }
+ data = sq_getscratchpad(v,size);
+ res = self->Read(data,size);
+ if(res <= 0)
+ return sq_throwerror(v,_SC("no data left to read"));
+ blobp = sqstd_createblob(v,res);
+ memcpy(blobp,data,res);
+ return 1;
+}
+
+#define SAFE_READN(ptr,len) { \
+ if(self->Read(ptr,len) != len) return sq_throwerror(v,_SC("io error")); \
+ }
+SQInteger _stream_readn(HSQUIRRELVM v)
+{
+ SETUP_STREAM(v);
+ SQInteger format;
+ sq_getinteger(v, 2, &format);
+ switch(format) {
+ case 'l': {
+ SQInteger i;
+ SAFE_READN(&i, sizeof(i));
+ sq_pushinteger(v, i);
+ }
+ break;
+ case 'i': {
+ SQInt32 i;
+ SAFE_READN(&i, sizeof(i));
+ sq_pushinteger(v, i);
+ }
+ break;
+ case 's': {
+ short s;
+ SAFE_READN(&s, sizeof(short));
+ sq_pushinteger(v, s);
+ }
+ break;
+ case 'w': {
+ unsigned short w;
+ SAFE_READN(&w, sizeof(unsigned short));
+ sq_pushinteger(v, w);
+ }
+ break;
+ case 'c': {
+ char c;
+ SAFE_READN(&c, sizeof(char));
+ sq_pushinteger(v, c);
+ }
+ break;
+ case 'b': {
+ unsigned char c;
+ SAFE_READN(&c, sizeof(unsigned char));
+ sq_pushinteger(v, c);
+ }
+ break;
+ case 'f': {
+ float f;
+ SAFE_READN(&f, sizeof(float));
+ sq_pushfloat(v, f);
+ }
+ break;
+ case 'd': {
+ double d;
+ SAFE_READN(&d, sizeof(double));
+ sq_pushfloat(v, (SQFloat)d);
+ }
+ break;
+ default:
+ return sq_throwerror(v, _SC("invalid format"));
+ }
+ return 1;
+}
+
+SQInteger _stream_writeblob(HSQUIRRELVM v)
+{
+ SQUserPointer data;
+ SQInteger size;
+ SETUP_STREAM(v);
+ if(SQ_FAILED(sqstd_getblob(v,2,&data)))
+ return sq_throwerror(v,_SC("invalid parameter"));
+ size = sqstd_getblobsize(v,2);
+ if(self->Write(data,size) != size)
+ return sq_throwerror(v,_SC("io error"));
+ sq_pushinteger(v,size);
+ return 1;
+}
+
+SQInteger _stream_writen(HSQUIRRELVM v)
+{
+ SETUP_STREAM(v);
+ SQInteger format, ti;
+ SQFloat tf;
+ sq_getinteger(v, 3, &format);
+ switch(format) {
+ case 'l': {
+ SQInteger i;
+ sq_getinteger(v, 2, &ti);
+ i = ti;
+ self->Write(&i, sizeof(SQInteger));
+ }
+ break;
+ case 'i': {
+ SQInt32 i;
+ sq_getinteger(v, 2, &ti);
+ i = (SQInt32)ti;
+ self->Write(&i, sizeof(SQInt32));
+ }
+ break;
+ case 's': {
+ short s;
+ sq_getinteger(v, 2, &ti);
+ s = (short)ti;
+ self->Write(&s, sizeof(short));
+ }
+ break;
+ case 'w': {
+ unsigned short w;
+ sq_getinteger(v, 2, &ti);
+ w = (unsigned short)ti;
+ self->Write(&w, sizeof(unsigned short));
+ }
+ break;
+ case 'c': {
+ char c;
+ sq_getinteger(v, 2, &ti);
+ c = (char)ti;
+ self->Write(&c, sizeof(char));
+ }
+ break;
+ case 'b': {
+ unsigned char b;
+ sq_getinteger(v, 2, &ti);
+ b = (unsigned char)ti;
+ self->Write(&b, sizeof(unsigned char));
+ }
+ break;
+ case 'f': {
+ float f;
+ sq_getfloat(v, 2, &tf);
+ f = (float)tf;
+ self->Write(&f, sizeof(float));
+ }
+ break;
+ case 'd': {
+ double d;
+ sq_getfloat(v, 2, &tf);
+ d = tf;
+ self->Write(&d, sizeof(double));
+ }
+ break;
+ default:
+ return sq_throwerror(v, _SC("invalid format"));
+ }
+ return 0;
+}
+
+SQInteger _stream_seek(HSQUIRRELVM v)
+{
+ SETUP_STREAM(v);
+ SQInteger offset, origin = SQ_SEEK_SET;
+ sq_getinteger(v, 2, &offset);
+ if(sq_gettop(v) > 2) {
+ SQInteger t;
+ sq_getinteger(v, 3, &t);
+ switch(t) {
+ case 'b': origin = SQ_SEEK_SET; break;
+ case 'c': origin = SQ_SEEK_CUR; break;
+ case 'e': origin = SQ_SEEK_END; break;
+ default: return sq_throwerror(v,_SC("invalid origin"));
+ }
+ }
+ sq_pushinteger(v, self->Seek(offset, origin));
+ return 1;
+}
+
+SQInteger _stream_tell(HSQUIRRELVM v)
+{
+ SETUP_STREAM(v);
+ sq_pushinteger(v, self->Tell());
+ return 1;
+}
+
+SQInteger _stream_len(HSQUIRRELVM v)
+{
+ SETUP_STREAM(v);
+ sq_pushinteger(v, self->Len());
+ return 1;
+}
+
+SQInteger _stream_flush(HSQUIRRELVM v)
+{
+ SETUP_STREAM(v);
+ if(!self->Flush())
+ sq_pushinteger(v, 1);
+ else
+ sq_pushnull(v);
+ return 1;
+}
+
+SQInteger _stream_eos(HSQUIRRELVM v)
+{
+ SETUP_STREAM(v);
+ if(self->EOS())
+ sq_pushinteger(v, 1);
+ else
+ sq_pushnull(v);
+ return 1;
+}
+
+static SQRegFunction _stream_methods[] = {
+ _DECL_STREAM_FUNC(readblob,2,_SC("xn")),
+ _DECL_STREAM_FUNC(readn,2,_SC("xn")),
+ _DECL_STREAM_FUNC(writeblob,-2,_SC("xx")),
+ _DECL_STREAM_FUNC(writen,3,_SC("xnn")),
+ _DECL_STREAM_FUNC(seek,-2,_SC("xnn")),
+ _DECL_STREAM_FUNC(tell,1,_SC("x")),
+ _DECL_STREAM_FUNC(len,1,_SC("x")),
+ _DECL_STREAM_FUNC(eos,1,_SC("x")),
+ _DECL_STREAM_FUNC(flush,1,_SC("x")),
+ {0,0}
+};
+
+void init_streamclass(HSQUIRRELVM v)
+{
+ sq_pushregistrytable(v);
+ sq_pushstring(v,_SC("std_stream"),-1);
+ if(SQ_FAILED(sq_get(v,-2))) {
+ sq_pushstring(v,_SC("std_stream"),-1);
+ sq_newclass(v,SQFalse);
+ sq_settypetag(v,-1,(SQUserPointer)SQSTD_STREAM_TYPE_TAG);
+ SQInteger i = 0;
+ while(_stream_methods[i].name != 0) {
+ SQRegFunction &f = _stream_methods[i];
+ sq_pushstring(v,f.name,-1);
+ sq_newclosure(v,f.f,0);
+ sq_setparamscheck(v,f.nparamscheck,f.typemask);
+ sq_createslot(v,-3);
+ i++;
+ }
+ sq_createslot(v,-3);
+ sq_pushroottable(v);
+ sq_pushstring(v,_SC("stream"),-1);
+ sq_pushstring(v,_SC("std_stream"),-1);
+ sq_get(v,-4);
+ sq_createslot(v,-3);
+ sq_pop(v,1);
+ }
+ else {
+ sq_pop(v,1); //result
+ }
+ sq_pop(v,1);
+}
+
+SQRESULT declare_stream(HSQUIRRELVM v,const SQChar* name,SQUserPointer typetag,const SQChar* reg_name,SQRegFunction *methods,SQRegFunction *globals)
+{
+ if(sq_gettype(v,-1) != OT_TABLE)
+ return sq_throwerror(v,_SC("table expected"));
+ SQInteger top = sq_gettop(v);
+ //create delegate
+ init_streamclass(v);
+ sq_pushregistrytable(v);
+ sq_pushstring(v,reg_name,-1);
+ sq_pushstring(v,_SC("std_stream"),-1);
+ if(SQ_SUCCEEDED(sq_get(v,-3))) {
+ sq_newclass(v,SQTrue);
+ sq_settypetag(v,-1,typetag);
+ SQInteger i = 0;
+ while(methods[i].name != 0) {
+ SQRegFunction &f = methods[i];
+ sq_pushstring(v,f.name,-1);
+ sq_newclosure(v,f.f,0);
+ sq_setparamscheck(v,f.nparamscheck,f.typemask);
+ sq_setnativeclosurename(v,-1,f.name);
+ sq_createslot(v,-3);
+ i++;
+ }
+ sq_createslot(v,-3);
+ sq_pop(v,1);
+
+ i = 0;
+ while(globals[i].name!=0)
+ {
+ SQRegFunction &f = globals[i];
+ sq_pushstring(v,f.name,-1);
+ sq_newclosure(v,f.f,0);
+ sq_setparamscheck(v,f.nparamscheck,f.typemask);
+ sq_setnativeclosurename(v,-1,f.name);
+ sq_createslot(v,-3);
+ i++;
+ }
+ //register the class in the target table
+ sq_pushstring(v,name,-1);
+ sq_pushregistrytable(v);
+ sq_pushstring(v,reg_name,-1);
+ sq_get(v,-2);
+ sq_remove(v,-2);
+ sq_createslot(v,-3);
+
+ sq_settop(v,top);
+ return SQ_OK;
+ }
+ sq_settop(v,top);
+ return SQ_ERROR;
+}
--- /dev/null
+/* see copyright notice in squirrel.h */
+#ifndef _SQSTD_STREAM_H_
+#define _SQSTD_STREAM_H_
+
+SQInteger _stream_readblob(HSQUIRRELVM v);
+SQInteger _stream_readline(HSQUIRRELVM v);
+SQInteger _stream_readn(HSQUIRRELVM v);
+SQInteger _stream_writeblob(HSQUIRRELVM v);
+SQInteger _stream_writen(HSQUIRRELVM v);
+SQInteger _stream_seek(HSQUIRRELVM v);
+SQInteger _stream_tell(HSQUIRRELVM v);
+SQInteger _stream_len(HSQUIRRELVM v);
+SQInteger _stream_eos(HSQUIRRELVM v);
+SQInteger _stream_flush(HSQUIRRELVM v);
+
+#define _DECL_STREAM_FUNC(name,nparams,typecheck) {_SC(#name),_stream_##name,nparams,typecheck}
+SQRESULT declare_stream(HSQUIRRELVM v,const SQChar* name,SQUserPointer typetag,const SQChar* reg_name,SQRegFunction *methods,SQRegFunction *globals);
+#endif /*_SQSTD_STREAM_H_*/
--- /dev/null
+/* see copyright notice in squirrel.h */
+#include <squirrel.h>
+#include <sqstdstring.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <assert.h>
+
+#ifdef SQUNICODE
+#define scstrchr wcschr
+#define scsnprintf wsnprintf
+#define scatoi _wtoi
+#define scstrtok wcstok
+#else
+#define scstrchr strchr
+#define scsnprintf snprintf
+#define scatoi atoi
+#define scstrtok strtok
+#endif
+#define MAX_FORMAT_LEN 20
+#define MAX_WFORMAT_LEN 3
+#define ADDITIONAL_FORMAT_SPACE (100*sizeof(SQChar))
+
+static SQInteger validate_format(HSQUIRRELVM v, SQChar *fmt, const SQChar *src, SQInteger n,SQInteger &width)
+{
+ SQChar swidth[MAX_WFORMAT_LEN];
+ SQInteger wc = 0;
+ SQInteger start = n;
+ fmt[0] = '%';
+ while (scstrchr(_SC("-+ #0"), src[n])) n++;
+ while (scisdigit(src[n])) {
+ swidth[wc] = src[n];
+ n++;
+ wc++;
+ if(wc>=MAX_WFORMAT_LEN)
+ return sq_throwerror(v,_SC("width format too long"));
+ }
+ swidth[wc] = '\0';
+ if(wc > 0) {
+ width = scatoi(swidth);
+ }
+ else
+ width = 0;
+ if (src[n] == '.') {
+ n++;
+
+ wc = 0;
+ while (scisdigit(src[n])) {
+ swidth[wc] = src[n];
+ n++;
+ wc++;
+ if(wc>=MAX_WFORMAT_LEN)
+ return sq_throwerror(v,_SC("precision format too long"));
+ }
+ swidth[wc] = '\0';
+ if(wc > 0) {
+ width += scatoi(swidth);
+ }
+ }
+ if (n-start > MAX_FORMAT_LEN )
+ return sq_throwerror(v,_SC("format too long"));
+ memcpy(&fmt[1],&src[start],((n-start)+1)*sizeof(SQChar));
+ fmt[(n-start)+2] = '\0';
+ return n;
+}
+
+
+SQRESULT sqstd_format(HSQUIRRELVM v,SQInteger nformatstringidx,SQInteger *outlen,SQChar **output)
+{
+ const SQChar *format;
+ SQChar *dest;
+ SQChar fmt[MAX_FORMAT_LEN];
+ sq_getstring(v,nformatstringidx,&format);
+ SQInteger allocated = (sq_getsize(v,nformatstringidx)+2)*sizeof(SQChar);
+ dest = sq_getscratchpad(v,allocated);
+ SQInteger n = 0,i = 0, nparam = nformatstringidx+1, w = 0;
+ while(format[n] != '\0') {
+ if(format[n] != '%') {
+ assert(i < allocated);
+ dest[i++] = format[n];
+ n++;
+ }
+ else if(format[n+1] == '%') { //handles %%
+ dest[i++] = '%';
+ n += 2;
+ }
+ else {
+ n++;
+ if( nparam > sq_gettop(v) )
+ return sq_throwerror(v,_SC("not enough paramters for the given format string"));
+ n = validate_format(v,fmt,format,n,w);
+ if(n < 0) return -1;
+ SQInteger addlen = 0;
+ SQInteger valtype = 0;
+ const SQChar *ts;
+ SQInteger ti;
+ SQFloat tf;
+ switch(format[n]) {
+ case 's':
+ if(SQ_FAILED(sq_getstring(v,nparam,&ts)))
+ return sq_throwerror(v,_SC("string expected for the specified format"));
+ addlen = (sq_getsize(v,nparam)*sizeof(SQChar))+((w+1)*sizeof(SQChar));
+ valtype = 's';
+ break;
+ case 'i': case 'd': case 'c':case 'o': case 'u': case 'x': case 'X':
+ if(SQ_FAILED(sq_getinteger(v,nparam,&ti)))
+ return sq_throwerror(v,_SC("integer expected for the specified format"));
+ addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar));
+ valtype = 'i';
+ break;
+ case 'f': case 'g': case 'G': case 'e': case 'E':
+ if(SQ_FAILED(sq_getfloat(v,nparam,&tf)))
+ return sq_throwerror(v,_SC("float expected for the specified format"));
+ addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar));
+ valtype = 'f';
+ break;
+ default:
+ return sq_throwerror(v,_SC("invalid format"));
+ }
+ n++;
+ allocated += addlen + sizeof(SQChar);
+ dest = sq_getscratchpad(v,allocated);
+ switch(valtype) {
+ case 's': i += scsprintf(&dest[i],fmt,ts); break;
+ case 'i': i += scsprintf(&dest[i],fmt,ti); break;
+ case 'f': i += scsprintf(&dest[i],fmt,tf); break;
+ };
+ nparam ++;
+ }
+ }
+ *outlen = i;
+ dest[i] = '\0';
+ *output = dest;
+ return SQ_OK;
+}
+
+static SQInteger _string_format(HSQUIRRELVM v)
+{
+ SQChar *dest = NULL;
+ SQInteger length = 0;
+ if(SQ_FAILED(sqstd_format(v,2,&length,&dest)))
+ return -1;
+ sq_pushstring(v,dest,length);
+ return 1;
+}
+
+static void __strip_l(const SQChar *str,const SQChar **start)
+{
+ const SQChar *t = str;
+ while(((*t) != '\0') && scisspace(*t)){ t++; }
+ *start = t;
+}
+
+static void __strip_r(const SQChar *str,SQInteger len,const SQChar **end)
+{
+ if(len == 0) {
+ *end = str;
+ return;
+ }
+ const SQChar *t = &str[len-1];
+ while(t != str && scisspace(*t)) { t--; }
+ *end = t+1;
+}
+
+static SQInteger _string_strip(HSQUIRRELVM v)
+{
+ const SQChar *str,*start,*end;
+ sq_getstring(v,2,&str);
+ SQInteger len = sq_getsize(v,2);
+ __strip_l(str,&start);
+ __strip_r(str,len,&end);
+ sq_pushstring(v,start,end - start);
+ return 1;
+}
+
+static SQInteger _string_lstrip(HSQUIRRELVM v)
+{
+ const SQChar *str,*start;
+ sq_getstring(v,2,&str);
+ __strip_l(str,&start);
+ sq_pushstring(v,start,-1);
+ return 1;
+}
+
+static SQInteger _string_rstrip(HSQUIRRELVM v)
+{
+ const SQChar *str,*end;
+ sq_getstring(v,2,&str);
+ SQInteger len = sq_getsize(v,2);
+ __strip_r(str,len,&end);
+ sq_pushstring(v,str,end - str);
+ return 1;
+}
+
+static SQInteger _string_split(HSQUIRRELVM v)
+{
+ const SQChar *str,*seps;
+ SQChar *stemp,*tok;
+ sq_getstring(v,2,&str);
+ sq_getstring(v,3,&seps);
+ if(sq_getsize(v,3) == 0) return sq_throwerror(v,_SC("empty separators string"));
+ SQInteger memsize = (sq_getsize(v,2)+1)*sizeof(SQChar);
+ stemp = sq_getscratchpad(v,memsize);
+ memcpy(stemp,str,memsize);
+ tok = scstrtok(stemp,seps);
+ sq_newarray(v,0);
+ while( tok != NULL ) {
+ sq_pushstring(v,tok,-1);
+ sq_arrayappend(v,-2);
+ tok = scstrtok( NULL, seps );
+ }
+ return 1;
+}
+
+#define SETUP_REX(v) \
+ SQRex *self = NULL; \
+ sq_getinstanceup(v,1,(SQUserPointer *)&self,0);
+
+static SQInteger _rexobj_releasehook(SQUserPointer p, SQInteger size)
+{
+ SQRex *self = ((SQRex *)p);
+ sqstd_rex_free(self);
+ return 1;
+}
+
+static SQInteger _regexp_match(HSQUIRRELVM v)
+{
+ SETUP_REX(v);
+ const SQChar *str;
+ sq_getstring(v,2,&str);
+ if(sqstd_rex_match(self,str) == SQTrue)
+ {
+ sq_pushbool(v,SQTrue);
+ return 1;
+ }
+ sq_pushbool(v,SQFalse);
+ return 1;
+}
+
+static void _addrexmatch(HSQUIRRELVM v,const SQChar *str,const SQChar *begin,const SQChar *end)
+{
+ sq_newtable(v);
+ sq_pushstring(v,_SC("begin"),-1);
+ sq_pushinteger(v,begin - str);
+ sq_rawset(v,-3);
+ sq_pushstring(v,_SC("end"),-1);
+ sq_pushinteger(v,end - str);
+ sq_rawset(v,-3);
+}
+
+static SQInteger _regexp_search(HSQUIRRELVM v)
+{
+ SETUP_REX(v);
+ const SQChar *str,*begin,*end;
+ SQInteger start = 0;
+ sq_getstring(v,2,&str);
+ if(sq_gettop(v) > 2) sq_getinteger(v,3,&start);
+ if(sqstd_rex_search(self,str+start,&begin,&end) == SQTrue) {
+ _addrexmatch(v,str,begin,end);
+ return 1;
+ }
+ return 0;
+}
+
+static SQInteger _regexp_capture(HSQUIRRELVM v)
+{
+ SETUP_REX(v);
+ const SQChar *str,*begin,*end;
+ SQInteger start = 0;
+ sq_getstring(v,2,&str);
+ if(sq_gettop(v) > 2) sq_getinteger(v,3,&start);
+ if(sqstd_rex_search(self,str+start,&begin,&end) == SQTrue) {
+ SQInteger n = sqstd_rex_getsubexpcount(self);
+ SQRexMatch match;
+ sq_newarray(v,0);
+ for(SQInteger i = 0;i < n; i++) {
+ sqstd_rex_getsubexp(self,i,&match);
+ if(match.len > 0)
+ _addrexmatch(v,str,match.begin,match.begin+match.len);
+ else
+ _addrexmatch(v,str,str,str); //empty match
+ sq_arrayappend(v,-2);
+ }
+ return 1;
+ }
+ return 0;
+}
+
+static SQInteger _regexp_subexpcount(HSQUIRRELVM v)
+{
+ SETUP_REX(v);
+ sq_pushinteger(v,sqstd_rex_getsubexpcount(self));
+ return 1;
+}
+
+static SQInteger _regexp_constructor(HSQUIRRELVM v)
+{
+ const SQChar *error,*pattern;
+ sq_getstring(v,2,&pattern);
+ SQRex *rex = sqstd_rex_compile(pattern,&error);
+ if(!rex) return sq_throwerror(v,error);
+ sq_setinstanceup(v,1,rex);
+ sq_setreleasehook(v,1,_rexobj_releasehook);
+ return 0;
+}
+
+static SQInteger _regexp__typeof(HSQUIRRELVM v)
+{
+ sq_pushstring(v,_SC("regexp"),-1);
+ return 1;
+}
+
+#define _DECL_REX_FUNC(name,nparams,pmask) {_SC(#name),_regexp_##name,nparams,pmask}
+static SQRegFunction rexobj_funcs[]={
+ _DECL_REX_FUNC(constructor,2,_SC(".s")),
+ _DECL_REX_FUNC(search,-2,_SC("xsn")),
+ _DECL_REX_FUNC(match,2,_SC("xs")),
+ _DECL_REX_FUNC(capture,-2,_SC("xsn")),
+ _DECL_REX_FUNC(subexpcount,1,_SC("x")),
+ _DECL_REX_FUNC(_typeof,1,_SC("x")),
+ {0,0}
+};
+
+#define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_string_##name,nparams,pmask}
+static SQRegFunction stringlib_funcs[]={
+ _DECL_FUNC(format,-2,_SC(".s")),
+ _DECL_FUNC(strip,2,_SC(".s")),
+ _DECL_FUNC(lstrip,2,_SC(".s")),
+ _DECL_FUNC(rstrip,2,_SC(".s")),
+ _DECL_FUNC(split,3,_SC(".ss")),
+ {0,0}
+};
+
+
+SQInteger sqstd_register_stringlib(HSQUIRRELVM v)
+{
+ sq_pushstring(v,_SC("regexp"),-1);
+ sq_newclass(v,SQFalse);
+ SQInteger i = 0;
+ while(rexobj_funcs[i].name != 0) {
+ SQRegFunction &f = rexobj_funcs[i];
+ sq_pushstring(v,f.name,-1);
+ sq_newclosure(v,f.f,0);
+ sq_setparamscheck(v,f.nparamscheck,f.typemask);
+ sq_setnativeclosurename(v,-1,f.name);
+ sq_createslot(v,-3);
+ i++;
+ }
+ sq_createslot(v,-3);
+
+ i = 0;
+ while(stringlib_funcs[i].name!=0)
+ {
+ sq_pushstring(v,stringlib_funcs[i].name,-1);
+ sq_newclosure(v,stringlib_funcs[i].f,0);
+ sq_setparamscheck(v,stringlib_funcs[i].nparamscheck,stringlib_funcs[i].typemask);
+ sq_setnativeclosurename(v,-1,stringlib_funcs[i].name);
+ sq_createslot(v,-3);
+ i++;
+ }
+ return 1;
+}
--- /dev/null
+/* see copyright notice in squirrel.h */
+#include <squirrel.h>
+#include <time.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sqstdsystem.h>
+
+#ifdef SQUNICODE
+#include <wchar.h>
+#define scgetenv _wgetenv
+#define scsystem _wsystem
+#define scasctime _wasctime
+#define scremove _wremove
+#define screname _wrename
+#else
+#define scgetenv getenv
+#define scsystem system
+#define scasctime asctime
+#define scremove remove
+#define screname rename
+#endif
+
+static SQInteger _system_getenv(HSQUIRRELVM v)
+{
+ const SQChar *s;
+ if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){
+ sq_pushstring(v,scgetenv(s),-1);
+ return 1;
+ }
+ return 0;
+}
+
+
+static SQInteger _system_system(HSQUIRRELVM v)
+{
+ const SQChar *s;
+ if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){
+ sq_pushinteger(v,scsystem(s));
+ return 1;
+ }
+ return sq_throwerror(v,_SC("wrong param"));
+}
+
+
+static SQInteger _system_clock(HSQUIRRELVM v)
+{
+ sq_pushfloat(v,((SQFloat)clock())/(SQFloat)CLOCKS_PER_SEC);
+ return 1;
+}
+
+static SQInteger _system_time(HSQUIRRELVM v)
+{
+ time_t t;
+ time(&t);
+ sq_pushinteger(v,*((SQInteger *)&t));
+ return 1;
+}
+
+static SQInteger _system_remove(HSQUIRRELVM v)
+{
+ const SQChar *s;
+ sq_getstring(v,2,&s);
+ if(scremove(s)==-1)
+ return sq_throwerror(v,_SC("remove() failed"));
+ return 0;
+}
+
+static SQInteger _system_rename(HSQUIRRELVM v)
+{
+ const SQChar *oldn,*newn;
+ sq_getstring(v,2,&oldn);
+ sq_getstring(v,3,&newn);
+ if(screname(oldn,newn)==-1)
+ return sq_throwerror(v,_SC("rename() failed"));
+ return 0;
+}
+
+static void _set_integer_slot(HSQUIRRELVM v,const SQChar *name,SQInteger val)
+{
+ sq_pushstring(v,name,-1);
+ sq_pushinteger(v,val);
+ sq_rawset(v,-3);
+}
+
+static SQInteger _system_date(HSQUIRRELVM v)
+{
+ time_t t;
+ SQInteger it;
+ SQInteger format = 'l';
+ if(sq_gettop(v) > 1) {
+ sq_getinteger(v,2,&it);
+ t = it;
+ if(sq_gettop(v) > 2) {
+ sq_getinteger(v,3,(SQInteger*)&format);
+ }
+ }
+ else {
+ time(&t);
+ }
+ tm *date;
+ if(format == 'u')
+ date = gmtime(&t);
+ else
+ date = localtime(&t);
+ if(!date)
+ return sq_throwerror(v,_SC("crt api failure"));
+ sq_newtable(v);
+ _set_integer_slot(v, _SC("sec"), date->tm_sec);
+ _set_integer_slot(v, _SC("min"), date->tm_min);
+ _set_integer_slot(v, _SC("hour"), date->tm_hour);
+ _set_integer_slot(v, _SC("day"), date->tm_mday);
+ _set_integer_slot(v, _SC("month"), date->tm_mon);
+ _set_integer_slot(v, _SC("year"), date->tm_year+1900);
+ _set_integer_slot(v, _SC("wday"), date->tm_wday);
+ _set_integer_slot(v, _SC("yday"), date->tm_yday);
+ return 1;
+}
+
+
+
+#define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_system_##name,nparams,pmask}
+static SQRegFunction systemlib_funcs[]={
+ _DECL_FUNC(getenv,2,_SC(".s")),
+ _DECL_FUNC(system,2,_SC(".s")),
+ _DECL_FUNC(clock,1,NULL),
+ _DECL_FUNC(time,1,NULL),
+ _DECL_FUNC(date,-1,_SC(".nn")),
+ _DECL_FUNC(remove,2,_SC(".s")),
+ _DECL_FUNC(rename,3,_SC(".ss")),
+ {0,0}
+};
+
+
+SQInteger sqstd_register_systemlib(HSQUIRRELVM v)
+{
+ SQInteger i=0;
+ while(systemlib_funcs[i].name!=0)
+ {
+ sq_pushstring(v,systemlib_funcs[i].name,-1);
+ sq_newclosure(v,systemlib_funcs[i].f,0);
+ sq_setparamscheck(v,systemlib_funcs[i].nparamscheck,systemlib_funcs[i].typemask);
+ sq_setnativeclosurename(v,-1,systemlib_funcs[i].name);
+ sq_createslot(v,-3);
+ i++;
+ }
+ return 1;
+}
--- /dev/null
+/*
+ see copyright notice in squirrel.h
+*/
+#include "sqpcheader.h"
+#include "sqvm.h"
+#include "sqstring.h"
+#include "sqtable.h"
+#include "sqarray.h"
+#include "sqfuncproto.h"
+#include "sqclosure.h"
+#include "squserdata.h"
+#include "sqcompiler.h"
+#include "sqfuncstate.h"
+#include "sqclass.h"
+
+bool sq_aux_gettypedarg(HSQUIRRELVM v,SQInteger idx,SQObjectType type,SQObjectPtr **o)
+{
+ *o = &stack_get(v,idx);
+ if(type(**o) != type){
+ SQObjectPtr oval = v->PrintObjVal(**o);
+ v->Raise_Error(_SC("wrong argument type, expected '%s' got '%.50s'"),IdType2Name(type),_stringval(oval));
+ return false;
+ }
+ return true;
+}
+
+#define _GETSAFE_OBJ(v,idx,type,o) { if(!sq_aux_gettypedarg(v,idx,type,&o)) return SQ_ERROR; }
+
+#define sq_aux_paramscheck(v,count) \
+{ \
+ if(sq_gettop(v) < count){ v->Raise_Error(_SC("not enough params in the stack")); return SQ_ERROR; }\
+}
+
+SQInteger sq_aux_throwobject(HSQUIRRELVM v,SQObjectPtr &e)
+{
+ v->_lasterror = e;
+ return SQ_ERROR;
+}
+
+SQInteger sq_aux_invalidtype(HSQUIRRELVM v,SQObjectType type)
+{
+ scsprintf(_ss(v)->GetScratchPad(100), _SC("unexpected type %s"), IdType2Name(type));
+ return sq_throwerror(v, _ss(v)->GetScratchPad(-1));
+}
+
+HSQUIRRELVM sq_open(SQInteger initialstacksize)
+{
+ SQSharedState *ss;
+ SQVM *v;
+ sq_new(ss, SQSharedState);
+ ss->Init();
+ v = (SQVM *)SQ_MALLOC(sizeof(SQVM));
+ new (v) SQVM(ss);
+ ss->_root_vm = v;
+ if(v->Init(NULL, initialstacksize)) {
+ return v;
+ } else {
+ sq_delete(v, SQVM);
+ return NULL;
+ }
+ return v;
+}
+
+HSQUIRRELVM sq_newthread(HSQUIRRELVM friendvm, SQInteger initialstacksize)
+{
+ SQSharedState *ss;
+ SQVM *v;
+ ss=_ss(friendvm);
+
+ v= (SQVM *)SQ_MALLOC(sizeof(SQVM));
+ new (v) SQVM(ss);
+
+ if(v->Init(friendvm, initialstacksize)) {
+ friendvm->Push(v);
+ return v;
+ } else {
+ sq_delete(v, SQVM);
+ return NULL;
+ }
+}
+
+SQInteger sq_getvmstate(HSQUIRRELVM v)
+{
+ if(v->_suspended)
+ return SQ_VMSTATE_SUSPENDED;
+ else {
+ if(v->_callsstacksize != 0) return SQ_VMSTATE_RUNNING;
+ else return SQ_VMSTATE_IDLE;
+ }
+}
+
+void sq_seterrorhandler(HSQUIRRELVM v)
+{
+ SQObject o = stack_get(v, -1);
+ if(sq_isclosure(o) || sq_isnativeclosure(o) || sq_isnull(o)) {
+ v->_errorhandler = o;
+ v->Pop();
+ }
+}
+
+void sq_setdebughook(HSQUIRRELVM v)
+{
+ SQObject o = stack_get(v,-1);
+ if(sq_isclosure(o) || sq_isnativeclosure(o) || sq_isnull(o)) {
+ v->_debughook = o;
+ v->Pop();
+ }
+}
+
+void sq_close(HSQUIRRELVM v)
+{
+ SQSharedState *ss = _ss(v);
+ _thread(ss->_root_vm)->Finalize();
+ sq_delete(ss, SQSharedState);
+}
+
+SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQChar *sourcename,SQBool raiseerror)
+{
+ SQObjectPtr o;
+ if(Compile(v, read, p, sourcename, o, raiseerror?true:false, _ss(v)->_debuginfo)) {
+ v->Push(SQClosure::Create(_ss(v), _funcproto(o)));
+ return SQ_OK;
+ }
+ return SQ_ERROR;
+}
+
+void sq_enabledebuginfo(HSQUIRRELVM v, SQBool enable)
+{
+ _ss(v)->_debuginfo = enable?true:false;
+}
+
+void sq_notifyallexceptions(HSQUIRRELVM v, SQBool enable)
+{
+ _ss(v)->_notifyallexceptions = enable?true:false;
+}
+
+void sq_addref(HSQUIRRELVM v,HSQOBJECT *po)
+{
+ if(!ISREFCOUNTED(type(*po))) return;
+#ifdef NO_GARBAGE_COLLECTOR
+ __AddRef(po->_type,po->_unVal);
+#else
+ _ss(v)->_refs_table.AddRef(*po);
+#endif
+}
+
+SQBool sq_release(HSQUIRRELVM v,HSQOBJECT *po)
+{
+ if(!ISREFCOUNTED(type(*po))) return SQTrue;
+#ifdef NO_GARBAGE_COLLECTOR
+ __Release(po->_type,po->_unVal);
+ return SQFalse; //the ret val doesn't work(and cannot be fixed)
+#else
+ return _ss(v)->_refs_table.Release(*po);
+#endif
+}
+
+const SQChar *sq_objtostring(HSQOBJECT *o)
+{
+ if(sq_type(*o) == OT_STRING) {
+ return _stringval(*o);
+ }
+ return NULL;
+}
+
+SQInteger sq_objtointeger(HSQOBJECT *o)
+{
+ if(sq_isnumeric(*o)) {
+ return tointeger(*o);
+ }
+ return 0;
+}
+
+SQFloat sq_objtofloat(HSQOBJECT *o)
+{
+ if(sq_isnumeric(*o)) {
+ return tofloat(*o);
+ }
+ return 0;
+}
+
+SQBool sq_objtobool(HSQOBJECT *o)
+{
+ if(sq_isbool(*o)) {
+ return _integer(*o);
+ }
+ return SQFalse;
+}
+
+void sq_pushnull(HSQUIRRELVM v)
+{
+ v->Push(_null_);
+}
+
+void sq_pushstring(HSQUIRRELVM v,const SQChar *s,SQInteger len)
+{
+ if(s)
+ v->Push(SQObjectPtr(SQString::Create(_ss(v), s, len)));
+ else v->Push(_null_);
+}
+
+void sq_pushinteger(HSQUIRRELVM v,SQInteger n)
+{
+ v->Push(n);
+}
+
+void sq_pushbool(HSQUIRRELVM v,SQBool b)
+{
+ v->Push(b?true:false);
+}
+
+void sq_pushfloat(HSQUIRRELVM v,SQFloat n)
+{
+ v->Push(n);
+}
+
+void sq_pushuserpointer(HSQUIRRELVM v,SQUserPointer p)
+{
+ v->Push(p);
+}
+
+SQUserPointer sq_newuserdata(HSQUIRRELVM v,SQUnsignedInteger size)
+{
+ SQUserData *ud = SQUserData::Create(_ss(v), size);
+ v->Push(ud);
+ return ud->_val;
+}
+
+void sq_newtable(HSQUIRRELVM v)
+{
+ v->Push(SQTable::Create(_ss(v), 0));
+}
+
+void sq_newarray(HSQUIRRELVM v,SQInteger size)
+{
+ v->Push(SQArray::Create(_ss(v), size));
+}
+
+SQRESULT sq_newclass(HSQUIRRELVM v,SQBool hasbase)
+{
+ SQClass *baseclass = NULL;
+ if(hasbase) {
+ SQObjectPtr &base = stack_get(v,-1);
+ if(type(base) != OT_CLASS)
+ return sq_throwerror(v,_SC("invalid base type"));
+ baseclass = _class(base);
+ }
+ SQClass *newclass = SQClass::Create(_ss(v), baseclass);
+ if(baseclass) v->Pop();
+ v->Push(newclass);
+ return SQ_OK;
+}
+
+SQBool sq_instanceof(HSQUIRRELVM v)
+{
+ SQObjectPtr &inst = stack_get(v,-1);
+ SQObjectPtr &cl = stack_get(v,-2);
+ if(type(inst) != OT_INSTANCE || type(cl) != OT_CLASS)
+ return sq_throwerror(v,_SC("invalid param type"));
+ return _instance(inst)->InstanceOf(_class(cl))?SQTrue:SQFalse;
+}
+
+SQRESULT sq_arrayappend(HSQUIRRELVM v,SQInteger idx)
+{
+ sq_aux_paramscheck(v,2);
+ SQObjectPtr *arr;
+ _GETSAFE_OBJ(v, idx, OT_ARRAY,arr);
+ _array(*arr)->Append(v->GetUp(-1));
+ v->Pop(1);
+ return SQ_OK;
+}
+
+SQRESULT sq_arraypop(HSQUIRRELVM v,SQInteger idx,SQBool pushval)
+{
+ sq_aux_paramscheck(v, 1);
+ SQObjectPtr *arr;
+ _GETSAFE_OBJ(v, idx, OT_ARRAY,arr);
+ if(_array(*arr)->Size() > 0) {
+ if(pushval != 0){ v->Push(_array(*arr)->Top()); }
+ _array(*arr)->Pop();
+ return SQ_OK;
+ }
+ return sq_throwerror(v, _SC("empty array"));
+}
+
+SQRESULT sq_arrayresize(HSQUIRRELVM v,SQInteger idx,SQInteger newsize)
+{
+ sq_aux_paramscheck(v,1);
+ SQObjectPtr *arr;
+ _GETSAFE_OBJ(v, idx, OT_ARRAY,arr);
+ if(newsize >= 0) {
+ _array(*arr)->Resize(newsize);
+ return SQ_OK;
+ }
+ return sq_throwerror(v,_SC("negative size"));
+}
+
+
+SQRESULT sq_arrayreverse(HSQUIRRELVM v,SQInteger idx)
+{
+ sq_aux_paramscheck(v, 1);
+ SQObjectPtr *o;
+ _GETSAFE_OBJ(v, idx, OT_ARRAY,o);
+ SQArray *arr = _array(*o);
+ if(arr->Size() > 0) {
+ SQObjectPtr t;
+ SQInteger size = arr->Size();
+ SQInteger n = size >> 1; size -= 1;
+ for(SQInteger i = 0; i < n; i++) {
+ t = arr->_values[i];
+ arr->_values[i] = arr->_values[size-i];
+ arr->_values[size-i] = t;
+ }
+ return SQ_OK;
+ }
+ return SQ_OK;
+}
+
+SQRESULT sq_arrayremove(HSQUIRRELVM v,SQInteger idx,SQInteger itemidx)
+{
+ sq_aux_paramscheck(v, 1);
+ SQObjectPtr *arr;
+ _GETSAFE_OBJ(v, idx, OT_ARRAY,arr);
+ return _array(*arr)->Remove(itemidx) ? SQ_OK : sq_throwerror(v,_SC("index out of range"));
+}
+
+SQRESULT sq_arrayinsert(HSQUIRRELVM v,SQInteger idx,SQInteger destpos)
+{
+ sq_aux_paramscheck(v, 1);
+ SQObjectPtr *arr;
+ _GETSAFE_OBJ(v, idx, OT_ARRAY,arr);
+ SQRESULT ret = _array(*arr)->Insert(destpos, v->GetUp(-1)) ? SQ_OK : sq_throwerror(v,_SC("index out of range"));
+ v->Pop();
+ return ret;
+}
+
+
+void sq_newclosure(HSQUIRRELVM v,SQFUNCTION func,SQUnsignedInteger nfreevars)
+{
+ SQNativeClosure *nc = SQNativeClosure::Create(_ss(v), func);
+ nc->_nparamscheck = 0;
+ for(SQUnsignedInteger i = 0; i < nfreevars; i++) {
+ nc->_outervalues.push_back(v->Top());
+ v->Pop();
+ }
+ v->Push(SQObjectPtr(nc));
+}
+
+SQRESULT sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger *nparams,SQUnsignedInteger *nfreevars)
+{
+ SQObject o = stack_get(v, idx);
+ if(sq_isclosure(o)) {
+ SQClosure *c = _closure(o);
+ SQFunctionProto *proto = _funcproto(c->_function);
+ *nparams = (SQUnsignedInteger)proto->_nparameters;
+ *nfreevars = (SQUnsignedInteger)c->_outervalues.size();
+ return SQ_OK;
+ }
+ return sq_throwerror(v,_SC("the object is not a closure"));
+}
+
+SQRESULT sq_setnativeclosurename(HSQUIRRELVM v,SQInteger idx,const SQChar *name)
+{
+ SQObject o = stack_get(v, idx);
+ if(sq_isnativeclosure(o)) {
+ SQNativeClosure *nc = _nativeclosure(o);
+ nc->_name = SQString::Create(_ss(v),name);
+ return SQ_OK;
+ }
+ return sq_throwerror(v,_SC("the object is not a nativeclosure"));
+}
+
+SQRESULT sq_setparamscheck(HSQUIRRELVM v,SQInteger nparamscheck,const SQChar *typemask)
+{
+ SQObject o = stack_get(v, -1);
+ if(!sq_isnativeclosure(o))
+ return sq_throwerror(v, _SC("native closure expected"));
+ SQNativeClosure *nc = _nativeclosure(o);
+ nc->_nparamscheck = nparamscheck;
+ if(typemask) {
+ SQIntVec res;
+ if(!CompileTypemask(res, typemask))
+ return sq_throwerror(v, _SC("invalid typemask"));
+ nc->_typecheck.copy(res);
+ }
+ else {
+ nc->_typecheck.resize(0);
+ }
+ if(nparamscheck == SQ_MATCHTYPEMASKSTRING) {
+ nc->_nparamscheck = nc->_typecheck.size();
+ }
+ return SQ_OK;
+}
+
+SQRESULT sq_bindenv(HSQUIRRELVM v,SQInteger idx)
+{
+ SQObjectPtr &o = stack_get(v,idx);
+ if(!sq_isnativeclosure(o) &&
+ !sq_isclosure(o))
+ return sq_throwerror(v,_SC("the target is not a closure"));
+ SQObjectPtr &env = stack_get(v,-1);
+ if(!sq_istable(env) &&
+ !sq_isclass(env) &&
+ !sq_isinstance(env))
+ return sq_throwerror(v,_SC("invalid environment"));
+ SQObjectPtr w = _refcounted(env)->GetWeakRef(type(env));
+ SQObjectPtr ret;
+ if(sq_isclosure(o)) {
+ SQClosure *c = _closure(o)->Clone();
+ c->_env = w;
+ ret = c;
+ }
+ else { //then must be a native closure
+ SQNativeClosure *c = _nativeclosure(o)->Clone();
+ c->_env = w;
+ ret = c;
+ }
+ v->Pop();
+ v->Push(ret);
+ return SQ_OK;
+}
+
+SQRESULT sq_clear(HSQUIRRELVM v,SQInteger idx)
+{
+ SQObject &o=stack_get(v,idx);
+ switch(type(o)) {
+ case OT_TABLE: _table(o)->Clear(); break;
+ case OT_ARRAY: _array(o)->Resize(0); break;
+ default:
+ return sq_throwerror(v, _SC("clear only works on table and array"));
+ break;
+
+ }
+ return SQ_OK;
+}
+
+void sq_pushroottable(HSQUIRRELVM v)
+{
+ v->Push(v->_roottable);
+}
+
+void sq_pushregistrytable(HSQUIRRELVM v)
+{
+ v->Push(_ss(v)->_registry);
+}
+
+void sq_pushconsttable(HSQUIRRELVM v)
+{
+ v->Push(_ss(v)->_consts);
+}
+
+SQRESULT sq_setroottable(HSQUIRRELVM v)
+{
+ SQObject o = stack_get(v, -1);
+ if(sq_istable(o) || sq_isnull(o)) {
+ v->_roottable = o;
+ v->Pop();
+ return SQ_OK;
+ }
+ return sq_throwerror(v, _SC("ivalid type"));
+}
+
+SQRESULT sq_setconsttable(HSQUIRRELVM v)
+{
+ SQObject o = stack_get(v, -1);
+ if(sq_istable(o)) {
+ _ss(v)->_consts = o;
+ v->Pop();
+ return SQ_OK;
+ }
+ return sq_throwerror(v, _SC("ivalid type, expected table"));
+}
+
+void sq_setforeignptr(HSQUIRRELVM v,SQUserPointer p)
+{
+ v->_foreignptr = p;
+}
+
+SQUserPointer sq_getforeignptr(HSQUIRRELVM v)
+{
+ return v->_foreignptr;
+}
+
+void sq_push(HSQUIRRELVM v,SQInteger idx)
+{
+ v->Push(stack_get(v, idx));
+}
+
+SQObjectType sq_gettype(HSQUIRRELVM v,SQInteger idx)
+{
+ return type(stack_get(v, idx));
+}
+
+
+void sq_tostring(HSQUIRRELVM v,SQInteger idx)
+{
+ SQObjectPtr &o = stack_get(v, idx);
+ SQObjectPtr res;
+ v->ToString(o,res);
+ v->Push(res);
+}
+
+void sq_tobool(HSQUIRRELVM v, SQInteger idx, SQBool *b)
+{
+ SQObjectPtr &o = stack_get(v, idx);
+ *b = v->IsFalse(o)?SQFalse:SQTrue;
+}
+
+SQRESULT sq_getinteger(HSQUIRRELVM v,SQInteger idx,SQInteger *i)
+{
+ SQObjectPtr &o = stack_get(v, idx);
+ if(sq_isnumeric(o)) {
+ *i = tointeger(o);
+ return SQ_OK;
+ }
+ return SQ_ERROR;
+}
+
+SQRESULT sq_getfloat(HSQUIRRELVM v,SQInteger idx,SQFloat *f)
+{
+ SQObjectPtr &o = stack_get(v, idx);
+ if(sq_isnumeric(o)) {
+ *f = tofloat(o);
+ return SQ_OK;
+ }
+ return SQ_ERROR;
+}
+
+SQRESULT sq_getbool(HSQUIRRELVM v,SQInteger idx,SQBool *b)
+{
+ SQObjectPtr &o = stack_get(v, idx);
+ if(sq_isbool(o)) {
+ *b = _integer(o);
+ return SQ_OK;
+ }
+ return SQ_ERROR;
+}
+
+SQRESULT sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar **c)
+{
+ SQObjectPtr *o = NULL;
+ _GETSAFE_OBJ(v, idx, OT_STRING,o);
+ *c = _stringval(*o);
+ return SQ_OK;
+}
+
+SQRESULT sq_getthread(HSQUIRRELVM v,SQInteger idx,HSQUIRRELVM *thread)
+{
+ SQObjectPtr *o = NULL;
+ _GETSAFE_OBJ(v, idx, OT_THREAD,o);
+ *thread = _thread(*o);
+ return SQ_OK;
+}
+
+SQRESULT sq_clone(HSQUIRRELVM v,SQInteger idx)
+{
+ SQObjectPtr &o = stack_get(v,idx);
+ v->Push(_null_);
+ if(!v->Clone(o, stack_get(v, -1))){
+ v->Pop();
+ return sq_aux_invalidtype(v, type(o));
+ }
+ return SQ_OK;
+}
+
+SQInteger sq_getsize(HSQUIRRELVM v, SQInteger idx)
+{
+ SQObjectPtr &o = stack_get(v, idx);
+ SQObjectType type = type(o);
+ switch(type) {
+ case OT_STRING: return _string(o)->_len;
+ case OT_TABLE: return _table(o)->CountUsed();
+ case OT_ARRAY: return _array(o)->Size();
+ case OT_USERDATA: return _userdata(o)->_size;
+ default:
+ return sq_aux_invalidtype(v, type);
+ }
+}
+
+SQRESULT sq_getuserdata(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p,SQUserPointer *typetag)
+{
+ SQObjectPtr *o = NULL;
+ _GETSAFE_OBJ(v, idx, OT_USERDATA,o);
+ (*p) = _userdataval(*o);
+ if(typetag) *typetag = _userdata(*o)->_typetag;
+ return SQ_OK;
+}
+
+SQRESULT sq_settypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer typetag)
+{
+ SQObjectPtr &o = stack_get(v,idx);
+ switch(type(o)) {
+ case OT_USERDATA: _userdata(o)->_typetag = typetag; break;
+ case OT_CLASS: _class(o)->_typetag = typetag; break;
+ default: return sq_throwerror(v,_SC("invalid object type"));
+ }
+ return SQ_OK;
+}
+
+SQRESULT sq_getobjtypetag(HSQOBJECT *o,SQUserPointer * typetag)
+{
+ switch(type(*o)) {
+ case OT_INSTANCE: *typetag = _instance(*o)->_class->_typetag; break;
+ case OT_USERDATA: *typetag = _userdata(*o)->_typetag; break;
+ case OT_CLASS: *typetag = _class(*o)->_typetag; break;
+ default: return SQ_ERROR;
+ }
+ return SQ_OK;
+}
+
+SQRESULT sq_gettypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer *typetag)
+{
+ SQObjectPtr &o = stack_get(v,idx);
+ if(SQ_FAILED(sq_getobjtypetag(&o,typetag)))
+ return sq_throwerror(v,_SC("invalid object type"));
+ return SQ_OK;
+}
+
+SQRESULT sq_getuserpointer(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p)
+{
+ SQObjectPtr *o = NULL;
+ _GETSAFE_OBJ(v, idx, OT_USERPOINTER,o);
+ (*p) = _userpointer(*o);
+ return SQ_OK;
+}
+
+SQRESULT sq_setinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer p)
+{
+ SQObjectPtr &o = stack_get(v,idx);
+ if(type(o) != OT_INSTANCE) return sq_throwerror(v,_SC("the object is not a class instance"));
+ _instance(o)->_userpointer = p;
+ return SQ_OK;
+}
+
+SQRESULT sq_setclassudsize(HSQUIRRELVM v, SQInteger idx, SQInteger udsize)
+{
+ SQObjectPtr &o = stack_get(v,idx);
+ if(type(o) != OT_CLASS) return sq_throwerror(v,_SC("the object is not a class"));
+ if(_class(o)->_locked) return sq_throwerror(v,_SC("the class is locked"));
+ _class(o)->_udsize = udsize;
+ return SQ_OK;
+}
+
+
+SQRESULT sq_getinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p,SQUserPointer typetag)
+{
+ SQObjectPtr &o = stack_get(v,idx);
+ if(type(o) != OT_INSTANCE) return sq_throwerror(v,_SC("the object is not a class instance"));
+ (*p) = _instance(o)->_userpointer;
+ if(typetag != 0) {
+ SQClass *cl = _instance(o)->_class;
+ do{
+ if(cl->_typetag == typetag)
+ return SQ_OK;
+ cl = cl->_base;
+ }while(cl != NULL);
+ return sq_throwerror(v,_SC("invalid type tag"));
+ }
+ return SQ_OK;
+}
+
+SQInteger sq_gettop(HSQUIRRELVM v)
+{
+ return (v->_top) - v->_stackbase;
+}
+
+void sq_settop(HSQUIRRELVM v, SQInteger newtop)
+{
+ SQInteger top = sq_gettop(v);
+ if(top > newtop)
+ sq_pop(v, top - newtop);
+ else
+ while(top++ < newtop) sq_pushnull(v);
+}
+
+void sq_pop(HSQUIRRELVM v, SQInteger nelemstopop)
+{
+ assert(v->_top >= nelemstopop);
+ v->Pop(nelemstopop);
+}
+
+void sq_poptop(HSQUIRRELVM v)
+{
+ assert(v->_top >= 1);
+ v->Pop();
+}
+
+
+void sq_remove(HSQUIRRELVM v, SQInteger idx)
+{
+ v->Remove(idx);
+}
+
+SQInteger sq_cmp(HSQUIRRELVM v)
+{
+ SQInteger res;
+ v->ObjCmp(stack_get(v, -1), stack_get(v, -2),res);
+ return res;
+}
+
+SQRESULT sq_newslot(HSQUIRRELVM v, SQInteger idx, SQBool bstatic)
+{
+ sq_aux_paramscheck(v, 3);
+ SQObjectPtr &self = stack_get(v, idx);
+ if(type(self) == OT_TABLE || type(self) == OT_CLASS) {
+ SQObjectPtr &key = v->GetUp(-2);
+ if(type(key) == OT_NULL) return sq_throwerror(v, _SC("null is not a valid key"));
+ v->NewSlot(self, key, v->GetUp(-1),bstatic?true:false);
+ v->Pop(2);
+ }
+ return SQ_OK;
+}
+
+SQRESULT sq_deleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval)
+{
+ sq_aux_paramscheck(v, 2);
+ SQObjectPtr *self;
+ _GETSAFE_OBJ(v, idx, OT_TABLE,self);
+ SQObjectPtr &key = v->GetUp(-1);
+ if(type(key) == OT_NULL) return sq_throwerror(v, _SC("null is not a valid key"));
+ SQObjectPtr res;
+ if(!v->DeleteSlot(*self, key, res)){
+ return SQ_ERROR;
+ }
+ if(pushval) v->GetUp(-1) = res;
+ else v->Pop(1);
+ return SQ_OK;
+}
+
+SQRESULT sq_set(HSQUIRRELVM v,SQInteger idx)
+{
+ SQObjectPtr &self = stack_get(v, idx);
+ if(v->Set(self, v->GetUp(-2), v->GetUp(-1),false)) {
+ v->Pop(2);
+ return SQ_OK;
+ }
+ v->Raise_IdxError(v->GetUp(-2));return SQ_ERROR;
+}
+
+SQRESULT sq_rawset(HSQUIRRELVM v,SQInteger idx)
+{
+ SQObjectPtr &self = stack_get(v, idx);
+ if(type(v->GetUp(-2)) == OT_NULL) return sq_throwerror(v, _SC("null key"));
+ switch(type(self)) {
+ case OT_TABLE:
+ _table(self)->NewSlot(v->GetUp(-2), v->GetUp(-1));
+ v->Pop(2);
+ return SQ_OK;
+ break;
+ case OT_CLASS:
+ _class(self)->NewSlot(_ss(v), v->GetUp(-2), v->GetUp(-1),false);
+ v->Pop(2);
+ return SQ_OK;
+ break;
+ case OT_INSTANCE:
+ if(_instance(self)->Set(v->GetUp(-2), v->GetUp(-1))) {
+ v->Pop(2);
+ return SQ_OK;
+ }
+ break;
+ case OT_ARRAY:
+ if(v->Set(self, v->GetUp(-2), v->GetUp(-1),false)) {
+ v->Pop(2);
+ return SQ_OK;
+ }
+ break;
+ default:
+ v->Pop(2);
+ return sq_throwerror(v, _SC("rawset works only on array/table/class and instance"));
+ }
+ v->Raise_IdxError(v->GetUp(-2));return SQ_ERROR;
+}
+
+SQRESULT sq_setdelegate(HSQUIRRELVM v,SQInteger idx)
+{
+ SQObjectPtr &self = stack_get(v, idx);
+ SQObjectPtr &mt = v->GetUp(-1);
+ SQObjectType type = type(self);
+ switch(type) {
+ case OT_TABLE:
+ if(type(mt) == OT_TABLE) {
+ if(!_table(self)->SetDelegate(_table(mt))) return sq_throwerror(v, _SC("delagate cycle")); v->Pop();}
+ else if(type(mt)==OT_NULL) {
+ _table(self)->SetDelegate(NULL); v->Pop(); }
+ else return sq_aux_invalidtype(v,type);
+ break;
+ case OT_USERDATA:
+ if(type(mt)==OT_TABLE) {
+ _userdata(self)->SetDelegate(_table(mt)); v->Pop(); }
+ else if(type(mt)==OT_NULL) {
+ _userdata(self)->SetDelegate(NULL); v->Pop(); }
+ else return sq_aux_invalidtype(v, type);
+ break;
+ default:
+ return sq_aux_invalidtype(v, type);
+ break;
+ }
+ return SQ_OK;
+}
+
+SQRESULT sq_rawdeleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval)
+{
+ sq_aux_paramscheck(v, 2);
+ SQObjectPtr *self;
+ _GETSAFE_OBJ(v, idx, OT_TABLE,self);
+ SQObjectPtr &key = v->GetUp(-1);
+ SQObjectPtr t;
+ if(_table(*self)->Get(key,t)) {
+ _table(*self)->Remove(key);
+ }
+ if(pushval != 0)
+ if(pushval) v->GetUp(-1) = t;
+ else
+ v->Pop(1);
+ return SQ_OK;
+}
+
+SQRESULT sq_getdelegate(HSQUIRRELVM v,SQInteger idx)
+{
+ SQObjectPtr &self=stack_get(v,idx);
+ switch(type(self)){
+ case OT_TABLE:
+ case OT_USERDATA:
+ if(!_delegable(self)->_delegate){
+ v->Push(_null_);
+ break;
+ }
+ v->Push(SQObjectPtr(_delegable(self)->_delegate));
+ break;
+ default: return sq_throwerror(v,_SC("wrong type")); break;
+ }
+ return SQ_OK;
+
+}
+
+SQRESULT sq_get(HSQUIRRELVM v,SQInteger idx)
+{
+ SQObjectPtr &self=stack_get(v,idx);
+ if(v->Get(self,v->GetUp(-1),v->GetUp(-1),false,false))
+ return SQ_OK;
+ v->Pop(1);
+ return sq_throwerror(v,_SC("the index doesn't exist"));
+}
+
+SQRESULT sq_rawget(HSQUIRRELVM v,SQInteger idx)
+{
+ SQObjectPtr &self=stack_get(v,idx);
+ switch(type(self)) {
+ case OT_TABLE:
+ if(_table(self)->Get(v->GetUp(-1),v->GetUp(-1)))
+ return SQ_OK;
+ break;
+ case OT_CLASS:
+ if(_class(self)->Get(v->GetUp(-1),v->GetUp(-1)))
+ return SQ_OK;
+ break;
+ case OT_INSTANCE:
+ if(_instance(self)->Get(v->GetUp(-1),v->GetUp(-1)))
+ return SQ_OK;
+ break;
+ case OT_ARRAY:
+ if(v->Get(self,v->GetUp(-1),v->GetUp(-1),false,false))
+ return SQ_OK;
+ break;
+ default:
+ v->Pop(1);
+ return sq_throwerror(v,_SC("rawget works only on array/table/instance and class"));
+ }
+ v->Pop(1);
+ return sq_throwerror(v,_SC("the index doesn't exist"));
+}
+
+SQRESULT sq_getstackobj(HSQUIRRELVM v,SQInteger idx,HSQOBJECT *po)
+{
+ *po=stack_get(v,idx);
+ return SQ_OK;
+}
+
+const SQChar *sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedInteger idx)
+{
+ SQUnsignedInteger cstksize=v->_callsstacksize;
+ SQUnsignedInteger lvl=(cstksize-level)-1;
+ SQInteger stackbase=v->_stackbase;
+ if(lvl<cstksize){
+ for(SQUnsignedInteger i=0;i<level;i++){
+ SQVM::CallInfo &ci=v->_callsstack[(cstksize-i)-1];
+ stackbase-=ci._prevstkbase;
+ }
+ SQVM::CallInfo &ci=v->_callsstack[lvl];
+ if(type(ci._closure)!=OT_CLOSURE)
+ return NULL;
+ SQClosure *c=_closure(ci._closure);
+ SQFunctionProto *func=_funcproto(c->_function);
+ if(func->_noutervalues > (SQInteger)idx) {
+ v->Push(c->_outervalues[idx]);
+ return _stringval(func->_outervalues[idx]._name);
+ }
+ idx -= func->_noutervalues;
+ return func->GetLocal(v,stackbase,idx,(SQInteger)(ci._ip-func->_instructions)-1);
+ }
+ return NULL;
+}
+
+void sq_pushobject(HSQUIRRELVM v,HSQOBJECT obj)
+{
+ v->Push(SQObjectPtr(obj));
+}
+
+void sq_resetobject(HSQOBJECT *po)
+{
+ po->_unVal.pUserPointer=NULL;po->_type=OT_NULL;
+}
+
+SQRESULT sq_throwerror(HSQUIRRELVM v,const SQChar *err)
+{
+ v->_lasterror=SQString::Create(_ss(v),err);
+ return -1;
+}
+
+void sq_reseterror(HSQUIRRELVM v)
+{
+ v->_lasterror = _null_;
+}
+
+void sq_getlasterror(HSQUIRRELVM v)
+{
+ v->Push(v->_lasterror);
+}
+
+void sq_reservestack(HSQUIRRELVM v,SQInteger nsize)
+{
+ if (((SQUnsignedInteger)v->_top + nsize) > v->_stack.size()) {
+ v->_stack.resize(v->_stack.size() + ((v->_top + nsize) - v->_stack.size()));
+ }
+}
+
+SQRESULT sq_resume(HSQUIRRELVM v,SQBool retval,SQBool raiseerror)
+{
+ if(type(v->GetUp(-1))==OT_GENERATOR){
+ v->Push(_null_); //retval
+ if(!v->Execute(v->GetUp(-2),v->_top,0,v->_top,v->GetUp(-1),raiseerror,SQVM::ET_RESUME_GENERATOR))
+ {v->Raise_Error(v->_lasterror); return SQ_ERROR;}
+ if(!retval)
+ v->Pop();
+ return SQ_OK;
+ }
+ return sq_throwerror(v,_SC("only generators can be resumed"));
+}
+
+SQRESULT sq_call(HSQUIRRELVM v,SQInteger params,SQBool retval,SQBool raiseerror)
+{
+ SQObjectPtr res;
+ if(v->Call(v->GetUp(-(params+1)),params,v->_top-params,res,raiseerror?true:false)){
+ if(!v->_suspended) {
+ v->Pop(params);//pop closure and args
+ }
+ if(retval){
+ v->Push(res); return SQ_OK;
+ }
+ return SQ_OK;
+ }
+ else {
+ v->Pop(params);
+ return SQ_ERROR;
+ }
+ if(!v->_suspended)
+ v->Pop(params);
+ return sq_throwerror(v,_SC("call failed"));
+}
+
+SQRESULT sq_suspendvm(HSQUIRRELVM v)
+{
+ return v->Suspend();
+}
+
+SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool wakeupret,SQBool retval,SQBool raiseerror,SQBool throwerror)
+{
+ SQObjectPtr ret;
+ if(!v->_suspended)
+ return sq_throwerror(v,_SC("cannot resume a vm that is not running any code"));
+ if(wakeupret) {
+ v->GetAt(v->_stackbase+v->_suspended_target)=v->GetUp(-1); //retval
+ v->Pop();
+ } else v->GetAt(v->_stackbase+v->_suspended_target)=_null_;
+ if(!v->Execute(_null_,v->_top,-1,-1,ret,raiseerror,throwerror?SQVM::ET_RESUME_THROW_VM : SQVM::ET_RESUME_VM))
+ return SQ_ERROR;
+ if(sq_getvmstate(v) == SQ_VMSTATE_IDLE) {
+ while (v->_top > 1) v->_stack[--v->_top] = _null_;
+ }
+ if(retval)
+ v->Push(ret);
+ return SQ_OK;
+}
+
+void sq_setreleasehook(HSQUIRRELVM v,SQInteger idx,SQRELEASEHOOK hook)
+{
+ if(sq_gettop(v) >= 1){
+ SQObjectPtr &ud=stack_get(v,idx);
+ switch( type(ud) ) {
+ case OT_USERDATA: _userdata(ud)->_hook = hook; break;
+ case OT_INSTANCE: _instance(ud)->_hook = hook; break;
+ case OT_CLASS: _class(ud)->_hook = hook; break;
+ default: break; //shutup compiler
+ }
+ }
+}
+
+void sq_setcompilererrorhandler(HSQUIRRELVM v,SQCOMPILERERROR f)
+{
+ _ss(v)->_compilererrorhandler = f;
+}
+
+SQRESULT sq_writeclosure(HSQUIRRELVM v,SQWRITEFUNC w,SQUserPointer up)
+{
+ SQObjectPtr *o = NULL;
+ _GETSAFE_OBJ(v, -1, OT_CLOSURE,o);
+ unsigned short tag = SQ_BYTECODE_STREAM_TAG;
+ if(w(up,&tag,2) != 2)
+ return sq_throwerror(v,_SC("io error"));
+ if(!_closure(*o)->Save(v,up,w))
+ return SQ_ERROR;
+ return SQ_OK;
+}
+
+SQRESULT sq_readclosure(HSQUIRRELVM v,SQREADFUNC r,SQUserPointer up)
+{
+ SQObjectPtr closure;
+
+ unsigned short tag;
+ if(r(up,&tag,2) != 2)
+ return sq_throwerror(v,_SC("io error"));
+ if(tag != SQ_BYTECODE_STREAM_TAG)
+ return sq_throwerror(v,_SC("invalid stream"));
+ if(!SQClosure::Load(v,up,r,closure))
+ return SQ_ERROR;
+ v->Push(closure);
+ return SQ_OK;
+}
+
+SQChar *sq_getscratchpad(HSQUIRRELVM v,SQInteger minsize)
+{
+ return _ss(v)->GetScratchPad(minsize);
+}
+
+SQInteger sq_collectgarbage(HSQUIRRELVM v)
+{
+#ifndef NO_GARBAGE_COLLECTOR
+ return _ss(v)->CollectGarbage(v);
+#else
+ return -1;
+#endif
+}
+
+const SQChar *sq_getfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval)
+{
+ SQObjectPtr &self = stack_get(v,idx);
+ const SQChar *name = NULL;
+ if(type(self) == OT_CLOSURE) {
+ if(_closure(self)->_outervalues.size()>nval) {
+ v->Push(_closure(self)->_outervalues[nval]);
+ SQFunctionProto *fp = _funcproto(_closure(self)->_function);
+ SQOuterVar &ov = fp->_outervalues[nval];
+ name = _stringval(ov._name);
+ }
+ }
+ return name;
+}
+
+SQRESULT sq_setfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval)
+{
+ SQObjectPtr &self=stack_get(v,idx);
+ switch(type(self))
+ {
+ case OT_CLOSURE:
+ if(_closure(self)->_outervalues.size()>nval){
+ _closure(self)->_outervalues[nval]=stack_get(v,-1);
+ }
+ else return sq_throwerror(v,_SC("invalid free var index"));
+ break;
+ case OT_NATIVECLOSURE:
+ if(_nativeclosure(self)->_outervalues.size()>nval){
+ _nativeclosure(self)->_outervalues[nval]=stack_get(v,-1);
+ }
+ else return sq_throwerror(v,_SC("invalid free var index"));
+ break;
+ default:
+ return sq_aux_invalidtype(v,type(self));
+ }
+ v->Pop(1);
+ return SQ_OK;
+}
+
+SQRESULT sq_setattributes(HSQUIRRELVM v,SQInteger idx)
+{
+ SQObjectPtr *o = NULL;
+ _GETSAFE_OBJ(v, idx, OT_CLASS,o);
+ SQObjectPtr &key = stack_get(v,-2);
+ SQObjectPtr &val = stack_get(v,-1);
+ SQObjectPtr attrs;
+ if(type(key) == OT_NULL) {
+ attrs = _class(*o)->_attributes;
+ _class(*o)->_attributes = val;
+ v->Pop(2);
+ v->Push(attrs);
+ return SQ_OK;
+ }else if(_class(*o)->GetAttributes(key,attrs)) {
+ _class(*o)->SetAttributes(key,val);
+ v->Pop(2);
+ v->Push(attrs);
+ return SQ_OK;
+ }
+ return sq_throwerror(v,_SC("wrong index"));
+}
+
+SQRESULT sq_getattributes(HSQUIRRELVM v,SQInteger idx)
+{
+ SQObjectPtr *o = NULL;
+ _GETSAFE_OBJ(v, idx, OT_CLASS,o);
+ SQObjectPtr &key = stack_get(v,-1);
+ SQObjectPtr attrs;
+ if(type(key) == OT_NULL) {
+ attrs = _class(*o)->_attributes;
+ v->Pop();
+ v->Push(attrs);
+ return SQ_OK;
+ }
+ else if(_class(*o)->GetAttributes(key,attrs)) {
+ v->Pop();
+ v->Push(attrs);
+ return SQ_OK;
+ }
+ return sq_throwerror(v,_SC("wrong index"));
+}
+
+SQRESULT sq_getbase(HSQUIRRELVM v,SQInteger idx)
+{
+ SQObjectPtr *o = NULL;
+ _GETSAFE_OBJ(v, idx, OT_CLASS,o);
+ if(_class(*o)->_base)
+ v->Push(SQObjectPtr(_class(*o)->_base));
+ else
+ v->Push(_null_);
+ return SQ_OK;
+}
+
+SQRESULT sq_getclass(HSQUIRRELVM v,SQInteger idx)
+{
+ SQObjectPtr *o = NULL;
+ _GETSAFE_OBJ(v, idx, OT_INSTANCE,o);
+ v->Push(SQObjectPtr(_instance(*o)->_class));
+ return SQ_OK;
+}
+
+SQRESULT sq_createinstance(HSQUIRRELVM v,SQInteger idx)
+{
+ SQObjectPtr *o = NULL;
+ _GETSAFE_OBJ(v, idx, OT_CLASS,o);
+ v->Push(_class(*o)->CreateInstance());
+ return SQ_OK;
+}
+
+void sq_weakref(HSQUIRRELVM v,SQInteger idx)
+{
+ SQObject &o=stack_get(v,idx);
+ if(ISREFCOUNTED(type(o))) {
+ v->Push(_refcounted(o)->GetWeakRef(type(o)));
+ return;
+ }
+ v->Push(o);
+}
+
+SQRESULT sq_getweakrefval(HSQUIRRELVM v,SQInteger idx)
+{
+ SQObjectPtr &o = stack_get(v,idx);
+ if(type(o) != OT_WEAKREF) {
+ return sq_throwerror(v,_SC("the object must be a weakref"));
+ }
+ v->Push(_weakref(o)->_obj);
+ return SQ_OK;
+}
+
+SQRESULT sq_getdefaultdelegate(HSQUIRRELVM v,SQObjectType t)
+{
+ SQSharedState *ss = _ss(v);
+ switch(t) {
+ case OT_TABLE: v->Push(ss->_table_default_delegate); break;
+ case OT_ARRAY: v->Push(ss->_array_default_delegate); break;
+ case OT_STRING: v->Push(ss->_string_default_delegate); break;
+ case OT_INTEGER: case OT_FLOAT: v->Push(ss->_number_default_delegate); break;
+ case OT_GENERATOR: v->Push(ss->_generator_default_delegate); break;
+ case OT_CLOSURE: case OT_NATIVECLOSURE: v->Push(ss->_closure_default_delegate); break;
+ case OT_THREAD: v->Push(ss->_thread_default_delegate); break;
+ case OT_CLASS: v->Push(ss->_class_default_delegate); break;
+ case OT_INSTANCE: v->Push(ss->_instance_default_delegate); break;
+ case OT_WEAKREF: v->Push(ss->_weakref_default_delegate); break;
+ default: return sq_throwerror(v,_SC("the type doesn't have a default delegate"));
+ }
+ return SQ_OK;
+}
+
+SQRESULT sq_next(HSQUIRRELVM v,SQInteger idx)
+{
+ SQObjectPtr o=stack_get(v,idx),&refpos = stack_get(v,-1),realkey,val;
+ if(type(o) == OT_GENERATOR) {
+ return sq_throwerror(v,_SC("cannot iterate a generator"));
+ }
+ int faketojump;
+ if(!v->FOREACH_OP(o,realkey,val,refpos,0,666,faketojump))
+ return SQ_ERROR;
+ if(faketojump != 666) {
+ v->Push(realkey);
+ v->Push(val);
+ return SQ_OK;
+ }
+ return SQ_ERROR;
+}
+
+struct BufState{
+ const SQChar *buf;
+ SQInteger ptr;
+ SQInteger size;
+};
+
+SQInteger buf_lexfeed(SQUserPointer file)
+{
+ BufState *buf=(BufState*)file;
+ if(buf->size<(buf->ptr+1))
+ return 0;
+ return buf->buf[buf->ptr++];
+}
+
+SQRESULT sq_compilebuffer(HSQUIRRELVM v,const SQChar *s,SQInteger size,const SQChar *sourcename,SQBool raiseerror) {
+ BufState buf;
+ buf.buf = s;
+ buf.size = size;
+ buf.ptr = 0;
+ return sq_compile(v, buf_lexfeed, &buf, sourcename, raiseerror);
+}
+
+void sq_move(HSQUIRRELVM dest,HSQUIRRELVM src,SQInteger idx)
+{
+ dest->Push(stack_get(src,idx));
+}
+
+void sq_setprintfunc(HSQUIRRELVM v, SQPRINTFUNCTION printfunc)
+{
+ _ss(v)->_printfunc = printfunc;
+}
+
+SQPRINTFUNCTION sq_getprintfunc(HSQUIRRELVM v)
+{
+ return _ss(v)->_printfunc;
+}
+
+void *sq_malloc(SQUnsignedInteger size)
+{
+ return SQ_MALLOC(size);
+}
+
+void *sq_realloc(void* p,SQUnsignedInteger oldsize,SQUnsignedInteger newsize)
+{
+ return SQ_REALLOC(p,oldsize,newsize);
+}
+
+void sq_free(void *p,SQUnsignedInteger size)
+{
+ SQ_FREE(p,size);
+}
--- /dev/null
+/* see copyright notice in squirrel.h */
+#ifndef _SQARRAY_H_
+#define _SQARRAY_H_
+
+struct SQArray : public CHAINABLE_OBJ
+{
+private:
+ SQArray(SQSharedState *ss,SQInteger nsize){_values.resize(nsize); INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);}
+ ~SQArray()
+ {
+ REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
+ }
+public:
+ static SQArray* Create(SQSharedState *ss,SQInteger nInitialSize){
+ SQArray *newarray=(SQArray*)SQ_MALLOC(sizeof(SQArray));
+ new (newarray) SQArray(ss,nInitialSize);
+ return newarray;
+ }
+#ifndef NO_GARBAGE_COLLECTOR
+ void Mark(SQCollectable **chain);
+#endif
+ void Finalize(){
+ _values.resize(0);
+ }
+ bool Get(const SQInteger nidx,SQObjectPtr &val)
+ {
+ if(nidx>=0 && nidx<(SQInteger)_values.size()){
+ SQObjectPtr &o = _values[nidx];
+ val = _realval(o);
+ return true;
+ }
+ else return false;
+ }
+ bool Set(const SQInteger nidx,const SQObjectPtr &val)
+ {
+ if(nidx>=0 && nidx<(SQInteger)_values.size()){
+ _values[nidx]=val;
+ return true;
+ }
+ else return false;
+ }
+ SQInteger Next(const SQObjectPtr &refpos,SQObjectPtr &outkey,SQObjectPtr &outval)
+ {
+ SQUnsignedInteger idx=TranslateIndex(refpos);
+ while(idx<_values.size()){
+ //first found
+ outkey=(SQInteger)idx;
+ SQObjectPtr &o = _values[idx];
+ outval = _realval(o);
+ //return idx for the next iteration
+ return ++idx;
+ }
+ //nothing to iterate anymore
+ return -1;
+ }
+ SQArray *Clone(){SQArray *anew=Create(_opt_ss(this),Size()); anew->_values.copy(_values); return anew; }
+ SQInteger Size() const {return _values.size();}
+ void Resize(SQInteger size,SQObjectPtr &fill = _null_) { _values.resize(size,fill); ShrinkIfNeeded(); }
+ void Reserve(SQInteger size) { _values.reserve(size); }
+ void Append(const SQObject &o){_values.push_back(o);}
+ void Extend(const SQArray *a);
+ SQObjectPtr &Top(){return _values.top();}
+ void Pop(){_values.pop_back(); ShrinkIfNeeded(); }
+ bool Insert(SQInteger idx,const SQObject &val){
+ if(idx < 0 || idx > (SQInteger)_values.size())
+ return false;
+ _values.insert(idx,val);
+ return true;
+ }
+ void ShrinkIfNeeded() {
+ if(_values.size() <= _values.capacity()>>2) //shrink the array
+ _values.shrinktofit();
+ }
+ bool Remove(SQInteger idx){
+ if(idx < 0 || idx >= (SQInteger)_values.size())
+ return false;
+ _values.remove(idx);
+ ShrinkIfNeeded();
+ return true;
+ }
+ void Release()
+ {
+ sq_delete(this,SQArray);
+ }
+ SQObjectPtrVec _values;
+};
+#endif //_SQARRAY_H_
--- /dev/null
+/*
+ see copyright notice in squirrel.h
+*/
+#include "sqpcheader.h"
+#include "sqvm.h"
+#include "sqstring.h"
+#include "sqtable.h"
+#include "sqarray.h"
+#include "sqfuncproto.h"
+#include "sqclosure.h"
+#include "sqclass.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <ctype.h>
+
+bool str2num(const SQChar *s,SQObjectPtr &res)
+{
+ SQChar *end;
+ if(scstrstr(s,_SC("."))){
+ SQFloat r = SQFloat(scstrtod(s,&end));
+ if(s == end) return false;
+ res = r;
+ return true;
+ }
+ else{
+ SQInteger r = SQInteger(scstrtol(s,&end,10));
+ if(s == end) return false;
+ res = r;
+ return true;
+ }
+}
+
+static SQInteger base_dummy(HSQUIRRELVM v)
+{
+ return 0;
+}
+
+#ifndef NO_GARBAGE_COLLECTOR
+static SQInteger base_collectgarbage(HSQUIRRELVM v)
+{
+ sq_pushinteger(v, sq_collectgarbage(v));
+ return 1;
+}
+#endif
+
+static SQInteger base_getroottable(HSQUIRRELVM v)
+{
+ v->Push(v->_roottable);
+ return 1;
+}
+
+static SQInteger base_getconsttable(HSQUIRRELVM v)
+{
+ v->Push(_ss(v)->_consts);
+ return 1;
+}
+
+
+static SQInteger base_setroottable(HSQUIRRELVM v)
+{
+ SQObjectPtr &o=stack_get(v,2);
+ if(SQ_FAILED(sq_setroottable(v))) return SQ_ERROR;
+ v->Push(o);
+ return 1;
+}
+
+static SQInteger base_setconsttable(HSQUIRRELVM v)
+{
+ SQObjectPtr &o=stack_get(v,2);
+ if(SQ_FAILED(sq_setconsttable(v))) return SQ_ERROR;
+ v->Push(o);
+ return 1;
+}
+
+static SQInteger base_seterrorhandler(HSQUIRRELVM v)
+{
+ sq_seterrorhandler(v);
+ return 0;
+}
+
+static SQInteger base_setdebughook(HSQUIRRELVM v)
+{
+ sq_setdebughook(v);
+ return 0;
+}
+
+static SQInteger base_enabledebuginfo(HSQUIRRELVM v)
+{
+ SQObjectPtr &o=stack_get(v,2);
+ sq_enabledebuginfo(v,(type(o) != OT_NULL)?1:0);
+ return 0;
+}
+
+static SQInteger base_getstackinfos(HSQUIRRELVM v)
+{
+ SQInteger level;
+ SQStackInfos si;
+ SQInteger seq = 0;
+ const SQChar *name = NULL;
+ sq_getinteger(v, -1, &level);
+ if (SQ_SUCCEEDED(sq_stackinfos(v, level, &si)))
+ {
+ const SQChar *fn = _SC("unknown");
+ const SQChar *src = _SC("unknown");
+ if(si.funcname)fn = si.funcname;
+ if(si.source)src = si.source;
+ sq_newtable(v);
+ sq_pushstring(v, _SC("func"), -1);
+ sq_pushstring(v, fn, -1);
+ sq_createslot(v, -3);
+ sq_pushstring(v, _SC("src"), -1);
+ sq_pushstring(v, src, -1);
+ sq_createslot(v, -3);
+ sq_pushstring(v, _SC("line"), -1);
+ sq_pushinteger(v, si.line);
+ sq_createslot(v, -3);
+ sq_pushstring(v, _SC("locals"), -1);
+ sq_newtable(v);
+ seq=0;
+ while ((name = sq_getlocal(v, level, seq))) {
+ sq_pushstring(v, name, -1);
+ sq_push(v, -2);
+ sq_createslot(v, -4);
+ sq_pop(v, 1);
+ seq++;
+ }
+ sq_createslot(v, -3);
+ return 1;
+ }
+
+ return 0;
+}
+
+static SQInteger base_assert(HSQUIRRELVM v)
+{
+ if(v->IsFalse(stack_get(v,2))){
+ return sq_throwerror(v,_SC("assertion failed"));
+ }
+ return 0;
+}
+
+static SQInteger get_slice_params(HSQUIRRELVM v,SQInteger &sidx,SQInteger &eidx,SQObjectPtr &o)
+{
+ SQInteger top = sq_gettop(v);
+ sidx=0;
+ eidx=0;
+ o=stack_get(v,1);
+ SQObjectPtr &start=stack_get(v,2);
+ if(type(start)!=OT_NULL && sq_isnumeric(start)){
+ sidx=tointeger(start);
+ }
+ if(top>2){
+ SQObjectPtr &end=stack_get(v,3);
+ if(sq_isnumeric(end)){
+ eidx=tointeger(end);
+ }
+ }
+ else {
+ eidx = sq_getsize(v,1);
+ }
+ return 1;
+}
+
+static SQInteger base_print(HSQUIRRELVM v)
+{
+ const SQChar *str;
+ sq_tostring(v,2);
+ sq_getstring(v,-1,&str);
+ if(_ss(v)->_printfunc) _ss(v)->_printfunc(v,_SC("%s"),str);
+ return 0;
+}
+
+static SQInteger base_compilestring(HSQUIRRELVM v)
+{
+ SQInteger nargs=sq_gettop(v);
+ const SQChar *src=NULL,*name=_SC("unnamedbuffer");
+ SQInteger size;
+ sq_getstring(v,2,&src);
+ size=sq_getsize(v,2);
+ if(nargs>2){
+ sq_getstring(v,3,&name);
+ }
+ if(SQ_SUCCEEDED(sq_compilebuffer(v,src,size,name,SQFalse)))
+ return 1;
+ else
+ return SQ_ERROR;
+}
+
+static SQInteger base_newthread(HSQUIRRELVM v)
+{
+ SQObjectPtr &func = stack_get(v,2);
+ SQInteger stksize = (_funcproto(_closure(func)->_function)->_stacksize << 1) +2;
+ HSQUIRRELVM newv = sq_newthread(v, (stksize < MIN_STACK_OVERHEAD + 2)? MIN_STACK_OVERHEAD + 2 : stksize);
+ sq_move(newv,v,-2);
+ return 1;
+}
+
+static SQInteger base_suspend(HSQUIRRELVM v)
+{
+ return sq_suspendvm(v);
+}
+
+static SQInteger base_array(HSQUIRRELVM v)
+{
+ SQArray *a;
+ SQObject &size = stack_get(v,2);
+ if(sq_gettop(v) > 2) {
+ a = SQArray::Create(_ss(v),0);
+ a->Resize(tointeger(size),stack_get(v,3));
+ }
+ else {
+ a = SQArray::Create(_ss(v),tointeger(size));
+ }
+ v->Push(a);
+ return 1;
+}
+
+static SQInteger base_type(HSQUIRRELVM v)
+{
+ SQObjectPtr &o = stack_get(v,2);
+ v->Push(SQString::Create(_ss(v),GetTypeName(o),-1));
+ return 1;
+}
+
+static SQRegFunction base_funcs[]={
+ //generic
+ {_SC("seterrorhandler"),base_seterrorhandler,2, NULL},
+ {_SC("setdebughook"),base_setdebughook,2, NULL},
+ {_SC("enabledebuginfo"),base_enabledebuginfo,2, NULL},
+ {_SC("getstackinfos"),base_getstackinfos,2, _SC(".n")},
+ {_SC("getroottable"),base_getroottable,1, NULL},
+ {_SC("setroottable"),base_setroottable,2, NULL},
+ {_SC("getconsttable"),base_getconsttable,1, NULL},
+ {_SC("setconsttable"),base_setconsttable,2, NULL},
+ {_SC("assert"),base_assert,2, NULL},
+ {_SC("print"),base_print,2, NULL},
+ {_SC("compilestring"),base_compilestring,-2, _SC(".ss")},
+ {_SC("newthread"),base_newthread,2, _SC(".c")},
+ {_SC("suspend"),base_suspend,-1, NULL},
+ {_SC("array"),base_array,-2, _SC(".n")},
+ {_SC("type"),base_type,2, NULL},
+ {_SC("dummy"),base_dummy,0,NULL},
+#ifndef NO_GARBAGE_COLLECTOR
+ {_SC("collectgarbage"),base_collectgarbage,1, _SC("t")},
+#endif
+ {0,0}
+};
+
+void sq_base_register(HSQUIRRELVM v)
+{
+ SQInteger i=0;
+ sq_pushroottable(v);
+ while(base_funcs[i].name!=0) {
+ sq_pushstring(v,base_funcs[i].name,-1);
+ sq_newclosure(v,base_funcs[i].f,0);
+ sq_setnativeclosurename(v,-1,base_funcs[i].name);
+ sq_setparamscheck(v,base_funcs[i].nparamscheck,base_funcs[i].typemask);
+ sq_createslot(v,-3);
+ i++;
+ }
+ sq_pushstring(v,_SC("_version_"),-1);
+ sq_pushstring(v,SQUIRREL_VERSION,-1);
+ sq_createslot(v,-3);
+ sq_pushstring(v,_SC("_charsize_"),-1);
+ sq_pushinteger(v,sizeof(SQChar));
+ sq_createslot(v,-3);
+ sq_pushstring(v,_SC("_intsize_"),-1);
+ sq_pushinteger(v,sizeof(SQInteger));
+ sq_createslot(v,-3);
+ sq_pushstring(v,_SC("_floatsize_"),-1);
+ sq_pushinteger(v,sizeof(SQFloat));
+ sq_createslot(v,-3);
+ sq_pop(v,1);
+}
+
+static SQInteger default_delegate_len(HSQUIRRELVM v)
+{
+ v->Push(SQInteger(sq_getsize(v,1)));
+ return 1;
+}
+
+static SQInteger default_delegate_tofloat(HSQUIRRELVM v)
+{
+ SQObjectPtr &o=stack_get(v,1);
+ switch(type(o)){
+ case OT_STRING:{
+ SQObjectPtr res;
+ if(str2num(_stringval(o),res)){
+ v->Push(SQObjectPtr(tofloat(res)));
+ break;
+ }}
+ return sq_throwerror(v, _SC("cannot convert the string"));
+ break;
+ case OT_INTEGER:case OT_FLOAT:
+ v->Push(SQObjectPtr(tofloat(o)));
+ break;
+ case OT_BOOL:
+ v->Push(SQObjectPtr((SQFloat)(_integer(o)?1:0)));
+ break;
+ default:
+ v->Push(_null_);
+ break;
+ }
+ return 1;
+}
+
+static SQInteger default_delegate_tointeger(HSQUIRRELVM v)
+{
+ SQObjectPtr &o=stack_get(v,1);
+ switch(type(o)){
+ case OT_STRING:{
+ SQObjectPtr res;
+ if(str2num(_stringval(o),res)){
+ v->Push(SQObjectPtr(tointeger(res)));
+ break;
+ }}
+ return sq_throwerror(v, _SC("cannot convert the string"));
+ break;
+ case OT_INTEGER:case OT_FLOAT:
+ v->Push(SQObjectPtr(tointeger(o)));
+ break;
+ case OT_BOOL:
+ v->Push(SQObjectPtr(_integer(o)?(SQInteger)1:(SQInteger)0));
+ break;
+ default:
+ v->Push(_null_);
+ break;
+ }
+ return 1;
+}
+
+static SQInteger default_delegate_tostring(HSQUIRRELVM v)
+{
+ sq_tostring(v,1);
+ return 1;
+}
+
+static SQInteger obj_delegate_weakref(HSQUIRRELVM v)
+{
+ sq_weakref(v,1);
+ return 1;
+}
+
+static SQInteger obj_clear(HSQUIRRELVM v)
+{
+ return sq_clear(v,-1);
+}
+
+
+static SQInteger number_delegate_tochar(HSQUIRRELVM v)
+{
+ SQObject &o=stack_get(v,1);
+ SQChar c = (SQChar)tointeger(o);
+ v->Push(SQString::Create(_ss(v),(const SQChar *)&c,1));
+ return 1;
+}
+
+
+/////////////////////////////////////////////////////////////////
+//TABLE DEFAULT DELEGATE
+
+static SQInteger table_rawdelete(HSQUIRRELVM v)
+{
+ if(SQ_FAILED(sq_rawdeleteslot(v,1,SQTrue)))
+ return SQ_ERROR;
+ return 1;
+}
+
+
+static SQInteger container_rawexists(HSQUIRRELVM v)
+{
+ if(SQ_SUCCEEDED(sq_rawget(v,-2))) {
+ sq_pushbool(v,SQTrue);
+ return 1;
+ }
+ sq_pushbool(v,SQFalse);
+ return 1;
+}
+
+static SQInteger table_rawset(HSQUIRRELVM v)
+{
+ return sq_rawset(v,-3);
+}
+
+
+static SQInteger table_rawget(HSQUIRRELVM v)
+{
+ return SQ_SUCCEEDED(sq_rawget(v,-2))?1:SQ_ERROR;
+}
+
+
+SQRegFunction SQSharedState::_table_default_delegate_funcz[]={
+ {_SC("len"),default_delegate_len,1, _SC("t")},
+ {_SC("rawget"),table_rawget,2, _SC("t")},
+ {_SC("rawset"),table_rawset,3, _SC("t")},
+ {_SC("rawdelete"),table_rawdelete,2, _SC("t")},
+ {_SC("rawin"),container_rawexists,2, _SC("t")},
+ {_SC("weakref"),obj_delegate_weakref,1, NULL },
+ {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
+ {_SC("clear"),obj_clear,1, _SC(".")},
+ {0,0}
+};
+
+//ARRAY DEFAULT DELEGATE///////////////////////////////////////
+
+static SQInteger array_append(HSQUIRRELVM v)
+{
+ return sq_arrayappend(v,-2);
+}
+
+static SQInteger array_extend(HSQUIRRELVM v)
+{
+ _array(stack_get(v,1))->Extend(_array(stack_get(v,2)));
+ return 0;
+}
+
+static SQInteger array_reverse(HSQUIRRELVM v)
+{
+ return sq_arrayreverse(v,-1);
+}
+
+static SQInteger array_pop(HSQUIRRELVM v)
+{
+ return SQ_SUCCEEDED(sq_arraypop(v,1,SQTrue))?1:SQ_ERROR;
+}
+
+static SQInteger array_top(HSQUIRRELVM v)
+{
+ SQObject &o=stack_get(v,1);
+ if(_array(o)->Size()>0){
+ v->Push(_array(o)->Top());
+ return 1;
+ }
+ else return sq_throwerror(v,_SC("top() on a empty array"));
+}
+
+static SQInteger array_insert(HSQUIRRELVM v)
+{
+ SQObject &o=stack_get(v,1);
+ SQObject &idx=stack_get(v,2);
+ SQObject &val=stack_get(v,3);
+ if(!_array(o)->Insert(tointeger(idx),val))
+ return sq_throwerror(v,_SC("index out of range"));
+ return 0;
+}
+
+static SQInteger array_remove(HSQUIRRELVM v)
+{
+ SQObject &o = stack_get(v, 1);
+ SQObject &idx = stack_get(v, 2);
+ if(!sq_isnumeric(idx)) return sq_throwerror(v, _SC("wrong type"));
+ SQObjectPtr val;
+ if(_array(o)->Get(tointeger(idx), val)) {
+ _array(o)->Remove(tointeger(idx));
+ v->Push(val);
+ return 1;
+ }
+ return sq_throwerror(v, _SC("idx out of range"));
+}
+
+static SQInteger array_resize(HSQUIRRELVM v)
+{
+ SQObject &o = stack_get(v, 1);
+ SQObject &nsize = stack_get(v, 2);
+ SQObjectPtr fill;
+ if(sq_isnumeric(nsize)) {
+ if(sq_gettop(v) > 2)
+ fill = stack_get(v, 3);
+ _array(o)->Resize(tointeger(nsize),fill);
+ return 0;
+ }
+ return sq_throwerror(v, _SC("size must be a number"));
+}
+
+
+//QSORT ala Sedgewick
+bool _qsort_compare(HSQUIRRELVM v,SQObjectPtr &arr,SQObjectPtr &a,SQObjectPtr &b,SQInteger func,SQInteger &ret)
+{
+ if(func < 0) {
+ if(!v->ObjCmp(a,b,ret)) return false;
+ }
+ else {
+ SQInteger top = sq_gettop(v);
+ sq_push(v, func);
+ sq_pushroottable(v);
+ v->Push(a);
+ v->Push(b);
+ if(SQ_FAILED(sq_call(v, 3, SQTrue, SQFalse))) {
+ if(!sq_isstring( v->_lasterror))
+ v->Raise_Error(_SC("compare func failed"));
+ return false;
+ }
+ sq_getinteger(v, -1, &ret);
+ sq_settop(v, top);
+ return true;
+ }
+ return true;
+}
+//QSORT ala Sedgewick
+bool _qsort(HSQUIRRELVM v,SQObjectPtr &arr, SQInteger l, SQInteger r,SQInteger func)
+{
+ SQInteger i, j;
+ SQArray *a=_array(arr);
+ SQObjectPtr pivot,t;
+ if( l < r ){
+ pivot = a->_values[l];
+ i = l; j = r+1;
+ while(1){
+ SQInteger ret;
+ do {
+ ++i;
+ if(i > r) break;
+ if(!_qsort_compare(v,arr,a->_values[i],pivot,func,ret))
+ return false;
+ } while( ret <= 0);
+ do {
+ --j;
+ if ( j < 0 ) {
+ v->Raise_Error( _SC("Invalid qsort, probably compare function defect") );
+ return false;
+ }
+ if(!_qsort_compare(v,arr,a->_values[j],pivot,func,ret))
+ return false;
+ }
+ while( ret > 0 );
+ if( i >= j ) break;
+ t = a->_values[i]; a->_values[i] = a->_values[j]; a->_values[j] = t;
+ }
+ t = a->_values[l]; a->_values[l] = a->_values[j]; a->_values[j] = t;
+ if(!_qsort( v, arr, l, j-1,func)) return false;
+ if(!_qsort( v, arr, j+1, r,func)) return false;
+ }
+ return true;
+}
+
+static SQInteger array_sort(HSQUIRRELVM v)
+{
+ SQInteger func = -1;
+ SQObjectPtr &o = stack_get(v,1);
+ SQObject &funcobj = stack_get(v,2);
+ if(_array(o)->Size() > 1) {
+ if(type(funcobj) == OT_CLOSURE || type(funcobj) == OT_NATIVECLOSURE) func = 2;
+ if(!_qsort(v, o, 0, _array(o)->Size()-1, func))
+ return SQ_ERROR;
+
+ }
+ return 0;
+}
+static SQInteger array_slice(HSQUIRRELVM v)
+{
+ SQInteger sidx,eidx;
+ SQObjectPtr o;
+ if(get_slice_params(v,sidx,eidx,o)==-1)return -1;
+ SQInteger alen = _array(o)->Size();
+ if(sidx < 0)sidx = alen + sidx;
+ if(eidx < 0)eidx = alen + eidx;
+ if(eidx < sidx)return sq_throwerror(v,_SC("wrong indexes"));
+ if(eidx > alen)return sq_throwerror(v,_SC("slice out of range"));
+ SQArray *arr=SQArray::Create(_ss(v),eidx-sidx);
+ SQObjectPtr t;
+ SQInteger count=0;
+ for(SQInteger i=sidx;i<eidx;i++){
+ _array(o)->Get(i,t);
+ arr->Set(count++,t);
+ }
+ v->Push(arr);
+ return 1;
+
+}
+
+SQRegFunction SQSharedState::_array_default_delegate_funcz[]={
+ {_SC("len"),default_delegate_len,1, _SC("a")},
+ {_SC("append"),array_append,2, _SC("a")},
+ {_SC("extend"),array_extend,2, _SC("aa")},
+ {_SC("push"),array_append,2, _SC("a")},
+ {_SC("pop"),array_pop,1, _SC("a")},
+ {_SC("top"),array_top,1, _SC("a")},
+ {_SC("insert"),array_insert,3, _SC("an")},
+ {_SC("remove"),array_remove,2, _SC("an")},
+ {_SC("resize"),array_resize,-2, _SC("an")},
+ {_SC("reverse"),array_reverse,1, _SC("a")},
+ {_SC("sort"),array_sort,-1, _SC("ac")},
+ {_SC("slice"),array_slice,-1, _SC("ann")},
+ {_SC("weakref"),obj_delegate_weakref,1, NULL },
+ {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
+ {_SC("clear"),obj_clear,1, _SC(".")},
+ {0,0}
+};
+
+//STRING DEFAULT DELEGATE//////////////////////////
+static SQInteger string_slice(HSQUIRRELVM v)
+{
+ SQInteger sidx,eidx;
+ SQObjectPtr o;
+ if(SQ_FAILED(get_slice_params(v,sidx,eidx,o)))return -1;
+ SQInteger slen = _string(o)->_len;
+ if(sidx < 0)sidx = slen + sidx;
+ if(eidx < 0)eidx = slen + eidx;
+ if(eidx < sidx) return sq_throwerror(v,_SC("wrong indexes"));
+ if(eidx > slen) return sq_throwerror(v,_SC("slice out of range"));
+ v->Push(SQString::Create(_ss(v),&_stringval(o)[sidx],eidx-sidx));
+ return 1;
+}
+
+static SQInteger string_find(HSQUIRRELVM v)
+{
+ SQInteger top,start_idx=0;
+ const SQChar *str,*substr,*ret;
+ if(((top=sq_gettop(v))>1) && SQ_SUCCEEDED(sq_getstring(v,1,&str)) && SQ_SUCCEEDED(sq_getstring(v,2,&substr))){
+ if(top>2)sq_getinteger(v,3,&start_idx);
+ if((sq_getsize(v,1)>start_idx) && (start_idx>=0)){
+ ret=scstrstr(&str[start_idx],substr);
+ if(ret){
+ sq_pushinteger(v,(SQInteger)(ret-str));
+ return 1;
+ }
+ }
+ return 0;
+ }
+ return sq_throwerror(v,_SC("invalid param"));
+}
+
+#define STRING_TOFUNCZ(func) static SQInteger string_##func(HSQUIRRELVM v) \
+{ \
+ SQObject str=stack_get(v,1); \
+ SQInteger len=_string(str)->_len; \
+ const SQChar *sThis=_stringval(str); \
+ SQChar *sNew=(_ss(v)->GetScratchPad(rsl(len))); \
+ for(SQInteger i=0;i<len;i++) sNew[i]=func(sThis[i]); \
+ v->Push(SQString::Create(_ss(v),sNew,len)); \
+ return 1; \
+}
+
+
+STRING_TOFUNCZ(tolower)
+STRING_TOFUNCZ(toupper)
+
+SQRegFunction SQSharedState::_string_default_delegate_funcz[]={
+ {_SC("len"),default_delegate_len,1, _SC("s")},
+ {_SC("tointeger"),default_delegate_tointeger,1, _SC("s")},
+ {_SC("tofloat"),default_delegate_tofloat,1, _SC("s")},
+ {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
+ {_SC("slice"),string_slice,-1, _SC(" s n n")},
+ {_SC("find"),string_find,-2, _SC("s s n ")},
+ {_SC("tolower"),string_tolower,1, _SC("s")},
+ {_SC("toupper"),string_toupper,1, _SC("s")},
+ {_SC("weakref"),obj_delegate_weakref,1, NULL },
+ {0,0}
+};
+
+//INTEGER DEFAULT DELEGATE//////////////////////////
+SQRegFunction SQSharedState::_number_default_delegate_funcz[]={
+ {_SC("tointeger"),default_delegate_tointeger,1, _SC("n|b")},
+ {_SC("tofloat"),default_delegate_tofloat,1, _SC("n|b")},
+ {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
+ {_SC("tochar"),number_delegate_tochar,1, _SC("n|b")},
+ {_SC("weakref"),obj_delegate_weakref,1, NULL },
+ {0,0}
+};
+
+//CLOSURE DEFAULT DELEGATE//////////////////////////
+static SQInteger closure_pcall(HSQUIRRELVM v)
+{
+ return SQ_SUCCEEDED(sq_call(v,sq_gettop(v)-1,SQTrue,SQFalse))?1:SQ_ERROR;
+}
+
+static SQInteger closure_call(HSQUIRRELVM v)
+{
+ return SQ_SUCCEEDED(sq_call(v,sq_gettop(v)-1,SQTrue,SQTrue))?1:SQ_ERROR;
+}
+
+static SQInteger _closure_acall(HSQUIRRELVM v,SQBool raiseerror)
+{
+ SQArray *aparams=_array(stack_get(v,2));
+ SQInteger nparams=aparams->Size();
+ v->Push(stack_get(v,1));
+ for(SQInteger i=0;i<nparams;i++)v->Push(aparams->_values[i]);
+ return SQ_SUCCEEDED(sq_call(v,nparams,SQTrue,raiseerror))?1:SQ_ERROR;
+}
+
+static SQInteger closure_acall(HSQUIRRELVM v)
+{
+ return _closure_acall(v,SQTrue);
+}
+
+static SQInteger closure_pacall(HSQUIRRELVM v)
+{
+ return _closure_acall(v,SQFalse);
+}
+
+static SQInteger closure_bindenv(HSQUIRRELVM v)
+{
+ if(SQ_FAILED(sq_bindenv(v,1)))
+ return SQ_ERROR;
+ return 1;
+}
+
+static SQInteger closure_getinfos(HSQUIRRELVM v) {
+ SQObject o = stack_get(v,1);
+ SQTable *res = SQTable::Create(_ss(v),4);
+ if(type(o) == OT_CLOSURE) {
+ SQFunctionProto *f = _funcproto(_closure(o)->_function);
+ SQInteger nparams = f->_nparameters + (f->_varparams?1:0);
+ SQObjectPtr params = SQArray::Create(_ss(v),nparams);
+ for(SQInteger n = 0; n<f->_nparameters; n++) {
+ _array(params)->Set((SQInteger)n,f->_parameters[n]);
+ }
+ if(f->_varparams) {
+ _array(params)->Set(nparams-1,SQString::Create(_ss(v),_SC("..."),-1));
+ }
+ res->NewSlot(SQString::Create(_ss(v),_SC("native"),-1),false);
+ res->NewSlot(SQString::Create(_ss(v),_SC("name"),-1),f->_name);
+ res->NewSlot(SQString::Create(_ss(v),_SC("src"),-1),f->_sourcename);
+ res->NewSlot(SQString::Create(_ss(v),_SC("parameters"),-1),params);
+ res->NewSlot(SQString::Create(_ss(v),_SC("varargs"),-1),f->_varparams);
+ }
+ else { //OT_NATIVECLOSURE
+ SQNativeClosure *nc = _nativeclosure(o);
+ res->NewSlot(SQString::Create(_ss(v),_SC("native"),-1),true);
+ res->NewSlot(SQString::Create(_ss(v),_SC("name"),-1),nc->_name);
+ res->NewSlot(SQString::Create(_ss(v),_SC("paramscheck"),-1),nc->_nparamscheck);
+ SQObjectPtr typecheck;
+ if(nc->_typecheck.size() > 0) {
+ typecheck =
+ SQArray::Create(_ss(v), nc->_typecheck.size());
+ for(SQUnsignedInteger n = 0; n<nc->_typecheck.size(); n++) {
+ _array(typecheck)->Set((SQInteger)n,nc->_typecheck[n]);
+ }
+ }
+ res->NewSlot(SQString::Create(_ss(v),_SC("typecheck"),-1),typecheck);
+ }
+ v->Push(res);
+ return 1;
+}
+
+
+SQRegFunction SQSharedState::_closure_default_delegate_funcz[]={
+ {_SC("call"),closure_call,-1, _SC("c")},
+ {_SC("pcall"),closure_pcall,-1, _SC("c")},
+ {_SC("acall"),closure_acall,2, _SC("ca")},
+ {_SC("pacall"),closure_pacall,2, _SC("ca")},
+ {_SC("weakref"),obj_delegate_weakref,1, NULL },
+ {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
+ {_SC("bindenv"),closure_bindenv,2, _SC("c x|y|t")},
+ {_SC("getinfos"),closure_getinfos,1, _SC("c")},
+ {0,0}
+};
+
+//GENERATOR DEFAULT DELEGATE
+static SQInteger generator_getstatus(HSQUIRRELVM v)
+{
+ SQObject &o=stack_get(v,1);
+ switch(_generator(o)->_state){
+ case SQGenerator::eSuspended:v->Push(SQString::Create(_ss(v),_SC("suspended")));break;
+ case SQGenerator::eRunning:v->Push(SQString::Create(_ss(v),_SC("running")));break;
+ case SQGenerator::eDead:v->Push(SQString::Create(_ss(v),_SC("dead")));break;
+ }
+ return 1;
+}
+
+SQRegFunction SQSharedState::_generator_default_delegate_funcz[]={
+ {_SC("getstatus"),generator_getstatus,1, _SC("g")},
+ {_SC("weakref"),obj_delegate_weakref,1, NULL },
+ {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
+ {0,0}
+};
+
+//THREAD DEFAULT DELEGATE
+
+static SQInteger thread_call(HSQUIRRELVM v)
+{
+
+ SQObjectPtr o = stack_get(v,1);
+ if(type(o) == OT_THREAD) {
+ SQInteger nparams = sq_gettop(v);
+ _thread(o)->Push(_thread(o)->_roottable);
+ for(SQInteger i = 2; i<(nparams+1); i++)
+ sq_move(_thread(o),v,i);
+ if(SQ_SUCCEEDED(sq_call(_thread(o),nparams,SQTrue,SQFalse))) {
+ sq_move(v,_thread(o),-1);
+ sq_pop(_thread(o),1);
+ return 1;
+ }
+ v->_lasterror = _thread(o)->_lasterror;
+ return SQ_ERROR;
+ }
+ return sq_throwerror(v,_SC("wrong parameter"));
+}
+
+static SQInteger thread_wakeup(HSQUIRRELVM v)
+{
+ SQObjectPtr o = stack_get(v,1);
+ if(type(o) == OT_THREAD) {
+ SQVM *thread = _thread(o);
+ SQInteger state = sq_getvmstate(thread);
+ if(state != SQ_VMSTATE_SUSPENDED) {
+ switch(state) {
+ case SQ_VMSTATE_IDLE:
+ return sq_throwerror(v,_SC("cannot wakeup a idle thread"));
+ break;
+ case SQ_VMSTATE_RUNNING:
+ return sq_throwerror(v,_SC("cannot wakeup a running thread"));
+ break;
+ }
+ }
+
+ SQInteger wakeupret = sq_gettop(v)>1?1:0;
+ if(wakeupret) {
+ sq_move(thread,v,2);
+ }
+ if(SQ_SUCCEEDED(sq_wakeupvm(thread,wakeupret,SQTrue,SQTrue,SQFalse))) {
+ sq_move(v,thread,-1);
+ sq_pop(thread,1); //pop retval
+ if(sq_getvmstate(thread) == SQ_VMSTATE_IDLE) {
+ sq_settop(thread,1); //pop roottable
+ }
+ return 1;
+ }
+ sq_settop(thread,1);
+ v->_lasterror = thread->_lasterror;
+ return SQ_ERROR;
+ }
+ return sq_throwerror(v,_SC("wrong parameter"));
+}
+
+static SQInteger thread_getstatus(HSQUIRRELVM v)
+{
+ SQObjectPtr &o = stack_get(v,1);
+ switch(sq_getvmstate(_thread(o))) {
+ case SQ_VMSTATE_IDLE:
+ sq_pushstring(v,_SC("idle"),-1);
+ break;
+ case SQ_VMSTATE_RUNNING:
+ sq_pushstring(v,_SC("running"),-1);
+ break;
+ case SQ_VMSTATE_SUSPENDED:
+ sq_pushstring(v,_SC("suspended"),-1);
+ break;
+ default:
+ return sq_throwerror(v,_SC("internal VM error"));
+ }
+ return 1;
+}
+
+SQRegFunction SQSharedState::_thread_default_delegate_funcz[] = {
+ {_SC("call"), thread_call, -1, _SC("v")},
+ {_SC("wakeup"), thread_wakeup, -1, _SC("v")},
+ {_SC("getstatus"), thread_getstatus, 1, _SC("v")},
+ {_SC("weakref"),obj_delegate_weakref,1, NULL },
+ {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
+ {0,0},
+};
+
+static SQInteger class_getattributes(HSQUIRRELVM v)
+{
+ if(SQ_SUCCEEDED(sq_getattributes(v,-2)))
+ return 1;
+ return SQ_ERROR;
+}
+
+static SQInteger class_setattributes(HSQUIRRELVM v)
+{
+ if(SQ_SUCCEEDED(sq_setattributes(v,-3)))
+ return 1;
+ return SQ_ERROR;
+}
+
+static SQInteger class_instance(HSQUIRRELVM v)
+{
+ if(SQ_SUCCEEDED(sq_createinstance(v,-1)))
+ return 1;
+ return SQ_ERROR;
+}
+
+SQRegFunction SQSharedState::_class_default_delegate_funcz[] = {
+ {_SC("getattributes"), class_getattributes, 2, _SC("y.")},
+ {_SC("setattributes"), class_setattributes, 3, _SC("y..")},
+ {_SC("rawin"),container_rawexists,2, _SC("y")},
+ {_SC("weakref"),obj_delegate_weakref,1, NULL },
+ {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
+ {_SC("instance"),class_instance,1, _SC("y")},
+ {0,0}
+};
+
+static SQInteger instance_getclass(HSQUIRRELVM v)
+{
+ if(SQ_SUCCEEDED(sq_getclass(v,1)))
+ return 1;
+ return SQ_ERROR;
+}
+
+SQRegFunction SQSharedState::_instance_default_delegate_funcz[] = {
+ {_SC("getclass"), instance_getclass, 1, _SC("x")},
+ {_SC("rawin"),container_rawexists,2, _SC("x")},
+ {_SC("weakref"),obj_delegate_weakref,1, NULL },
+ {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
+ {0,0}
+};
+
+static SQInteger weakref_ref(HSQUIRRELVM v)
+{
+ if(SQ_FAILED(sq_getweakrefval(v,1)))
+ return SQ_ERROR;
+ return 1;
+}
+
+SQRegFunction SQSharedState::_weakref_default_delegate_funcz[] = {
+ {_SC("ref"),weakref_ref,1, _SC("r")},
+ {_SC("weakref"),obj_delegate_weakref,1, NULL },
+ {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
+ {0,0}
+};
+
+
--- /dev/null
+/*
+ see copyright notice in squirrel.h
+*/
+#include "sqpcheader.h"
+#include "sqvm.h"
+#include "sqtable.h"
+#include "sqclass.h"
+#include "sqclosure.h"
+
+SQClass::SQClass(SQSharedState *ss,SQClass *base)
+{
+ _base = base;
+ _typetag = 0;
+ _hook = NULL;
+ _udsize = 0;
+ _metamethods.resize(MT_LAST); //size it to max size
+ if(_base) {
+ _defaultvalues.copy(base->_defaultvalues);
+ _methods.copy(base->_methods);
+ _metamethods.copy(base->_metamethods);
+ __ObjAddRef(_base);
+ }
+ _members = base?base->_members->Clone() : SQTable::Create(ss,0);
+ __ObjAddRef(_members);
+ _locked = false;
+ INIT_CHAIN();
+ ADD_TO_CHAIN(&_sharedstate->_gc_chain, this);
+}
+
+void SQClass::Finalize() {
+ _attributes = _null_;
+ _defaultvalues.resize(0);
+ _methods.resize(0);
+ _metamethods.resize(0);
+ __ObjRelease(_members);
+ if(_base) {
+ __ObjRelease(_base);
+ }
+}
+
+SQClass::~SQClass()
+{
+ REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
+ Finalize();
+}
+
+bool SQClass::NewSlot(SQSharedState *ss,const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic)
+{
+ SQObjectPtr temp;
+ if(_locked)
+ return false; //the class already has an instance so cannot be modified
+ if(_members->Get(key,temp) && _isfield(temp)) //overrides the default value
+ {
+ _defaultvalues[_member_idx(temp)].val = val;
+ return true;
+ }
+ if(type(val) == OT_CLOSURE || type(val) == OT_NATIVECLOSURE || bstatic) {
+ SQInteger mmidx;
+ if((type(val) == OT_CLOSURE || type(val) == OT_NATIVECLOSURE) &&
+ (mmidx = ss->GetMetaMethodIdxByName(key)) != -1) {
+ _metamethods[mmidx] = val;
+ }
+ else {
+ if(type(temp) == OT_NULL) {
+ SQClassMember m;
+ m.val = val;
+ _members->NewSlot(key,SQObjectPtr(_make_method_idx(_methods.size())));
+ _methods.push_back(m);
+ }
+ else {
+ _methods[_member_idx(temp)].val = val;
+ }
+ }
+ return true;
+ }
+ SQClassMember m;
+ m.val = val;
+ _members->NewSlot(key,SQObjectPtr(_make_field_idx(_defaultvalues.size())));
+ _defaultvalues.push_back(m);
+ return true;
+}
+
+SQInstance *SQClass::CreateInstance()
+{
+ if(!_locked) Lock();
+ return SQInstance::Create(_opt_ss(this),this);
+}
+
+SQInteger SQClass::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval)
+{
+ SQObjectPtr oval;
+ SQInteger idx = _members->Next(false,refpos,outkey,oval);
+ if(idx != -1) {
+ if(_ismethod(oval)) {
+ outval = _methods[_member_idx(oval)].val;
+ }
+ else {
+ SQObjectPtr &o = _defaultvalues[_member_idx(oval)].val;
+ outval = _realval(o);
+ }
+ }
+ return idx;
+}
+
+bool SQClass::SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val)
+{
+ SQObjectPtr idx;
+ if(_members->Get(key,idx)) {
+ if(_isfield(idx))
+ _defaultvalues[_member_idx(idx)].attrs = val;
+ else
+ _methods[_member_idx(idx)].attrs = val;
+ return true;
+ }
+ return false;
+}
+
+bool SQClass::GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval)
+{
+ SQObjectPtr idx;
+ if(_members->Get(key,idx)) {
+ outval = (_isfield(idx)?_defaultvalues[_member_idx(idx)].attrs:_methods[_member_idx(idx)].attrs);
+ return true;
+ }
+ return false;
+}
+
+///////////////////////////////////////////////////////////////////////
+void SQInstance::Init(SQSharedState *ss)
+{
+ _userpointer = NULL;
+ _hook = NULL;
+ __ObjAddRef(_class);
+ _delegate = _class->_members;
+ INIT_CHAIN();
+ ADD_TO_CHAIN(&_sharedstate->_gc_chain, this);
+}
+
+SQInstance::SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize)
+{
+ _memsize = memsize;
+ _class = c;
+ SQUnsignedInteger nvalues = _class->_defaultvalues.size();
+ for(SQUnsignedInteger n = 0; n < nvalues; n++) {
+ new (&_values[n]) SQObjectPtr(_class->_defaultvalues[n].val);
+ }
+ Init(ss);
+}
+
+SQInstance::SQInstance(SQSharedState *ss, SQInstance *i, SQInteger memsize)
+{
+ _memsize = memsize;
+ _class = i->_class;
+ SQUnsignedInteger nvalues = _class->_defaultvalues.size();
+ for(SQUnsignedInteger n = 0; n < nvalues; n++) {
+ new (&_values[n]) SQObjectPtr(i->_values[n]);
+ }
+ Init(ss);
+}
+
+void SQInstance::Finalize()
+{
+ SQUnsignedInteger nvalues = _class->_defaultvalues.size();
+ __ObjRelease(_class);
+ for(SQUnsignedInteger i = 0; i < nvalues; i++) {
+ _values[i] = _null_;
+ }
+}
+
+SQInstance::~SQInstance()
+{
+ REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
+ if(_class){ Finalize(); } //if _class is null it was already finalized by the GC
+}
+
+bool SQInstance::GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res)
+{
+ if(type(_class->_metamethods[mm]) != OT_NULL) {
+ res = _class->_metamethods[mm];
+ return true;
+ }
+ return false;
+}
+
+bool SQInstance::InstanceOf(SQClass *trg)
+{
+ SQClass *parent = _class;
+ while(parent != NULL) {
+ if(parent == trg)
+ return true;
+ parent = parent->_base;
+ }
+ return false;
+}
--- /dev/null
+/* see copyright notice in squirrel.h */
+#ifndef _SQCLASS_H_
+#define _SQCLASS_H_
+
+struct SQInstance;
+
+struct SQClassMember {
+ SQClassMember(){}
+ SQClassMember(const SQClassMember &o) {
+ val = o.val;
+ attrs = o.attrs;
+ }
+ SQObjectPtr val;
+ SQObjectPtr attrs;
+};
+
+typedef sqvector<SQClassMember> SQClassMemberVec;
+
+#define MEMBER_TYPE_METHOD 0x01000000
+#define MEMBER_TYPE_FIELD 0x02000000
+
+#define _ismethod(o) (_integer(o)&MEMBER_TYPE_METHOD)
+#define _isfield(o) (_integer(o)&MEMBER_TYPE_FIELD)
+#define _make_method_idx(i) ((SQInteger)(MEMBER_TYPE_METHOD|i))
+#define _make_field_idx(i) ((SQInteger)(MEMBER_TYPE_FIELD|i))
+#define _member_type(o) (_integer(o)&0xFF000000)
+#define _member_idx(o) (_integer(o)&0x00FFFFFF)
+
+struct SQClass : public CHAINABLE_OBJ
+{
+ SQClass(SQSharedState *ss,SQClass *base);
+public:
+ static SQClass* Create(SQSharedState *ss,SQClass *base) {
+ SQClass *newclass = (SQClass *)SQ_MALLOC(sizeof(SQClass));
+ new (newclass) SQClass(ss, base);
+ return newclass;
+ }
+ ~SQClass();
+ bool NewSlot(SQSharedState *ss, const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic);
+ bool Get(const SQObjectPtr &key,SQObjectPtr &val) {
+ if(_members->Get(key,val)) {
+ if(_isfield(val)) {
+ SQObjectPtr &o = _defaultvalues[_member_idx(val)].val;
+ val = _realval(o);
+ }
+ else {
+ val = _methods[_member_idx(val)].val;
+ }
+ return true;
+ }
+ return false;
+ }
+ bool SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val);
+ bool GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval);
+ void Lock() { _locked = true; if(_base) _base->Lock(); }
+ void Release() {
+ if (_hook) { _hook(_typetag,0);}
+ sq_delete(this, SQClass);
+ }
+ void Finalize();
+#ifndef NO_GARBAGE_COLLECTOR
+ void Mark(SQCollectable ** );
+#endif
+ SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);
+ SQInstance *CreateInstance();
+ SQTable *_members;
+ SQClass *_base;
+ SQClassMemberVec _defaultvalues;
+ SQClassMemberVec _methods;
+ SQObjectPtrVec _metamethods;
+ SQObjectPtr _attributes;
+ SQUserPointer _typetag;
+ SQRELEASEHOOK _hook;
+ bool _locked;
+ SQInteger _udsize;
+};
+
+#define calcinstancesize(_theclass_) \
+ (_theclass_->_udsize + sizeof(SQInstance) + (sizeof(SQObjectPtr)*(_theclass_->_defaultvalues.size()>0?_theclass_->_defaultvalues.size()-1:0)))
+
+struct SQInstance : public SQDelegable
+{
+ void Init(SQSharedState *ss);
+ SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize);
+ SQInstance(SQSharedState *ss, SQInstance *c, SQInteger memsize);
+public:
+ static SQInstance* Create(SQSharedState *ss,SQClass *theclass) {
+
+ SQInteger size = calcinstancesize(theclass);
+ SQInstance *newinst = (SQInstance *)SQ_MALLOC(size);
+ new (newinst) SQInstance(ss, theclass,size);
+ if(theclass->_udsize) {
+ newinst->_userpointer = ((unsigned char *)newinst) + (size - theclass->_udsize);
+ }
+ return newinst;
+ }
+ SQInstance *Clone(SQSharedState *ss)
+ {
+ SQInteger size = calcinstancesize(_class);
+ SQInstance *newinst = (SQInstance *)SQ_MALLOC(size);
+ new (newinst) SQInstance(ss, this,size);
+ if(_class->_udsize) {
+ newinst->_userpointer = ((unsigned char *)newinst) + (size - _class->_udsize);
+ }
+ return newinst;
+ }
+ ~SQInstance();
+ bool Get(const SQObjectPtr &key,SQObjectPtr &val) {
+ if(_class->_members->Get(key,val)) {
+ if(_isfield(val)) {
+ SQObjectPtr &o = _values[_member_idx(val)];
+ val = _realval(o);
+ }
+ else {
+ val = _class->_methods[_member_idx(val)].val;
+ }
+ return true;
+ }
+ return false;
+ }
+ bool Set(const SQObjectPtr &key,const SQObjectPtr &val) {
+ SQObjectPtr idx;
+ if(_class->_members->Get(key,idx) && _isfield(idx)) {
+ _values[_member_idx(idx)] = val;
+ return true;
+ }
+ return false;
+ }
+ void Release() {
+ _uiRef++;
+ if (_hook) { _hook(_userpointer,0);}
+ _uiRef--;
+ if(_uiRef > 0) return;
+ SQInteger size = _memsize;
+ this->~SQInstance();
+ SQ_FREE(this, size);
+ }
+ void Finalize();
+#ifndef NO_GARBAGE_COLLECTOR
+ void Mark(SQCollectable ** );
+#endif
+ bool InstanceOf(SQClass *trg);
+ bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res);
+
+ SQClass *_class;
+ SQUserPointer _userpointer;
+ SQRELEASEHOOK _hook;
+ SQInteger _memsize;
+ SQObjectPtr _values[1];
+};
+
+#endif //_SQCLASS_H_
--- /dev/null
+/* see copyright notice in squirrel.h */
+#ifndef _SQCLOSURE_H_
+#define _SQCLOSURE_H_
+
+struct SQFunctionProto;
+
+struct SQClosure : public CHAINABLE_OBJ
+{
+private:
+ SQClosure(SQSharedState *ss,SQFunctionProto *func){_function=func; INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);}
+public:
+ static SQClosure *Create(SQSharedState *ss,SQFunctionProto *func){
+ SQClosure *nc=(SQClosure*)SQ_MALLOC(sizeof(SQClosure));
+ new (nc) SQClosure(ss,func);
+ return nc;
+ }
+ void Release(){
+ sq_delete(this,SQClosure);
+ }
+ SQClosure *Clone()
+ {
+ SQClosure * ret = SQClosure::Create(_opt_ss(this),_funcproto(_function));
+ ret->_env = _env;
+ ret->_outervalues.copy(_outervalues);
+ ret->_defaultparams.copy(_defaultparams);
+ return ret;
+ }
+ ~SQClosure()
+ {
+ REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
+ }
+ bool Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write);
+ static bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret);
+#ifndef NO_GARBAGE_COLLECTOR
+ void Mark(SQCollectable **chain);
+ void Finalize(){_outervalues.resize(0); }
+#endif
+ SQObjectPtr _env;
+ SQObjectPtr _function;
+ SQObjectPtrVec _outervalues;
+ SQObjectPtrVec _defaultparams;
+};
+//////////////////////////////////////////////
+struct SQGenerator : public CHAINABLE_OBJ
+{
+ enum SQGeneratorState{eRunning,eSuspended,eDead};
+private:
+ SQGenerator(SQSharedState *ss,SQClosure *closure){_closure=closure;_state=eRunning;_ci._generator=NULL;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);}
+public:
+ static SQGenerator *Create(SQSharedState *ss,SQClosure *closure){
+ SQGenerator *nc=(SQGenerator*)SQ_MALLOC(sizeof(SQGenerator));
+ new (nc) SQGenerator(ss,closure);
+ return nc;
+ }
+ ~SQGenerator()
+ {
+ REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
+ }
+ void Kill(){
+ _state=eDead;
+ _stack.resize(0);
+ _closure=_null_;}
+ void Release(){
+ sq_delete(this,SQGenerator);
+ }
+ bool Yield(SQVM *v);
+ bool Resume(SQVM *v,SQInteger target);
+#ifndef NO_GARBAGE_COLLECTOR
+ void Mark(SQCollectable **chain);
+ void Finalize(){_stack.resize(0);_closure=_null_;}
+#endif
+ SQObjectPtr _closure;
+ SQObjectPtrVec _stack;
+ SQObjectPtrVec _vargsstack;
+ SQVM::CallInfo _ci;
+ ExceptionsTraps _etraps;
+ SQGeneratorState _state;
+};
+
+struct SQNativeClosure : public CHAINABLE_OBJ
+{
+private:
+ SQNativeClosure(SQSharedState *ss,SQFUNCTION func){_function=func;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); }
+public:
+ static SQNativeClosure *Create(SQSharedState *ss,SQFUNCTION func)
+ {
+ SQNativeClosure *nc=(SQNativeClosure*)SQ_MALLOC(sizeof(SQNativeClosure));
+ new (nc) SQNativeClosure(ss,func);
+ return nc;
+ }
+ SQNativeClosure *Clone()
+ {
+ SQNativeClosure * ret = SQNativeClosure::Create(_opt_ss(this),_function);
+ ret->_env = _env;
+ ret->_name = _name;
+ ret->_outervalues.copy(_outervalues);
+ ret->_typecheck.copy(_typecheck);
+ ret->_nparamscheck = _nparamscheck;
+ return ret;
+ }
+ ~SQNativeClosure()
+ {
+ REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
+ }
+ void Release(){
+ sq_delete(this,SQNativeClosure);
+ }
+#ifndef NO_GARBAGE_COLLECTOR
+ void Mark(SQCollectable **chain);
+ void Finalize(){_outervalues.resize(0);}
+#endif
+ SQInteger _nparamscheck;
+ SQIntVec _typecheck;
+ SQObjectPtrVec _outervalues;
+ SQObjectPtr _env;
+ SQFUNCTION _function;
+ SQObjectPtr _name;
+};
+
+
+
+#endif //_SQCLOSURE_H_
--- /dev/null
+/*
+ see copyright notice in squirrel.h
+*/
+#include "sqpcheader.h"
+#include <stdarg.h>
+#include <setjmp.h>
+#include "sqopcodes.h"
+#include "sqstring.h"
+#include "sqfuncproto.h"
+#include "sqcompiler.h"
+#include "sqfuncstate.h"
+#include "sqlexer.h"
+#include "sqvm.h"
+#include "sqtable.h"
+
+#define DEREF_NO_DEREF -1
+#define DEREF_FIELD -2
+
+struct ExpState
+{
+ ExpState()
+ {
+ _deref = DEREF_NO_DEREF;
+ _freevar = false;
+ _class_or_delete = false;
+ _funcarg = false;
+ }
+ bool _class_or_delete;
+ bool _funcarg;
+ bool _freevar;
+ SQInteger _deref;
+};
+
+typedef sqvector<ExpState> ExpStateVec;
+
+#define _exst (_expstates.top())
+
+#define BEGIN_BREAKBLE_BLOCK() SQInteger __nbreaks__=_fs->_unresolvedbreaks.size(); \
+ SQInteger __ncontinues__=_fs->_unresolvedcontinues.size(); \
+ _fs->_breaktargets.push_back(0);_fs->_continuetargets.push_back(0);
+
+#define END_BREAKBLE_BLOCK(continue_target) {__nbreaks__=_fs->_unresolvedbreaks.size()-__nbreaks__; \
+ __ncontinues__=_fs->_unresolvedcontinues.size()-__ncontinues__; \
+ if(__ncontinues__>0)ResolveContinues(_fs,__ncontinues__,continue_target); \
+ if(__nbreaks__>0)ResolveBreaks(_fs,__nbreaks__); \
+ _fs->_breaktargets.pop_back();_fs->_continuetargets.pop_back();}
+
+class SQCompiler
+{
+public:
+ SQCompiler(SQVM *v, SQLEXREADFUNC rg, SQUserPointer up, const SQChar* sourcename, bool raiseerror, bool lineinfo)
+ {
+ _vm=v;
+ _lex.Init(_ss(v), rg, up,ThrowError,this);
+ _sourcename = SQString::Create(_ss(v), sourcename);
+ _lineinfo = lineinfo;_raiseerror = raiseerror;
+ compilererror = NULL;
+ }
+ static void ThrowError(void *ud, const SQChar *s) {
+ SQCompiler *c = (SQCompiler *)ud;
+ c->Error(s);
+ }
+ void Error(const SQChar *s, ...)
+ {
+ static SQChar temp[256];
+ va_list vl;
+ va_start(vl, s);
+ scvsprintf(temp, s, vl);
+ va_end(vl);
+ compilererror = temp;
+ longjmp(_errorjmp,1);
+ }
+ void Lex(){ _token = _lex.Lex();}
+ void PushExpState(){ _expstates.push_back(ExpState()); }
+ bool IsDerefToken(SQInteger tok)
+ {
+ switch(tok){
+ case _SC('='): case _SC('('): case TK_NEWSLOT:
+ case TK_MODEQ: case TK_MULEQ: case TK_DIVEQ: case TK_MINUSEQ: case TK_PLUSEQ: case TK_PLUSPLUS: case TK_MINUSMINUS: return true;
+ }
+ return false;
+ }
+ ExpState PopExpState()
+ {
+ ExpState ret = _expstates.top();
+ _expstates.pop_back();
+ return ret;
+ }
+ SQObject Expect(SQInteger tok)
+ {
+
+ if(_token != tok) {
+ if(_token == TK_CONSTRUCTOR && tok == TK_IDENTIFIER) {
+ //ret = SQString::Create(_ss(_vm),_SC("constructor"));
+ //do nothing
+ }
+ else {
+ const SQChar *etypename;
+ if(tok > 255) {
+ switch(tok)
+ {
+ case TK_IDENTIFIER:
+ etypename = _SC("IDENTIFIER");
+ break;
+ case TK_STRING_LITERAL:
+ etypename = _SC("STRING_LITERAL");
+ break;
+ case TK_INTEGER:
+ etypename = _SC("INTEGER");
+ break;
+ case TK_FLOAT:
+ etypename = _SC("FLOAT");
+ break;
+ default:
+ etypename = _lex.Tok2Str(tok);
+ }
+ Error(_SC("expected '%s'"), etypename);
+ }
+ Error(_SC("expected '%c'"), tok);
+ }
+ }
+ SQObjectPtr ret;
+ switch(tok)
+ {
+ case TK_IDENTIFIER:
+ ret = _fs->CreateString(_lex._svalue);
+ break;
+ case TK_STRING_LITERAL:
+ ret = _fs->CreateString(_lex._svalue,_lex._longstr.size()-1);
+ break;
+ case TK_INTEGER:
+ ret = SQObjectPtr(_lex._nvalue);
+ break;
+ case TK_FLOAT:
+ ret = SQObjectPtr(_lex._fvalue);
+ break;
+ }
+ Lex();
+ return ret;
+ }
+ bool IsEndOfStatement() { return ((_lex._prevtoken == _SC('\n')) || (_token == SQUIRREL_EOB) || (_token == _SC('}')) || (_token == _SC(';'))); }
+ void OptionalSemicolon()
+ {
+ if(_token == _SC(';')) { Lex(); return; }
+ if(!IsEndOfStatement()) {
+ Error(_SC("end of statement expected (; or lf)"));
+ }
+ }
+ void MoveIfCurrentTargetIsLocal() {
+ SQInteger trg = _fs->TopTarget();
+ if(_fs->IsLocal(trg)) {
+ trg = _fs->PopTarget(); //no pops the target and move it
+ _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), trg);
+ }
+ }
+ bool Compile(SQObjectPtr &o)
+ {
+ _debugline = 1;
+ _debugop = 0;
+
+ SQFuncState funcstate(_ss(_vm), NULL,ThrowError,this);
+ funcstate._name = SQString::Create(_ss(_vm), _SC("main"));
+ _fs = &funcstate;
+ _fs->AddParameter(_fs->CreateString(_SC("this")));
+ _fs->_sourcename = _sourcename;
+ SQInteger stacksize = _fs->GetStackSize();
+ if(setjmp(_errorjmp) == 0) {
+ Lex();
+ while(_token > 0){
+ Statement();
+ if(_lex._prevtoken != _SC('}')) OptionalSemicolon();
+ }
+ CleanStack(stacksize);
+ _fs->AddLineInfos(_lex._currentline, _lineinfo, true);
+ _fs->AddInstruction(_OP_RETURN, 0xFF);
+ _fs->SetStackSize(0);
+ o =_fs->BuildProto();
+#ifdef _DEBUG_DUMP
+ _fs->Dump(_funcproto(o));
+#endif
+ }
+ else {
+ if(_raiseerror && _ss(_vm)->_compilererrorhandler) {
+ _ss(_vm)->_compilererrorhandler(_vm, compilererror, type(_sourcename) == OT_STRING?_stringval(_sourcename):_SC("unknown"),
+ _lex._currentline, _lex._currentcolumn);
+ }
+ _vm->_lasterror = SQString::Create(_ss(_vm), compilererror, -1);
+ return false;
+ }
+ return true;
+ }
+ void Statements()
+ {
+ while(_token != _SC('}') && _token != TK_DEFAULT && _token != TK_CASE) {
+ Statement();
+ if(_lex._prevtoken != _SC('}') && _lex._prevtoken != _SC(';')) OptionalSemicolon();
+ }
+ }
+ void Statement()
+ {
+ _fs->AddLineInfos(_lex._currentline, _lineinfo);
+ switch(_token){
+ case _SC(';'): Lex(); break;
+ case TK_IF: IfStatement(); break;
+ case TK_WHILE: WhileStatement(); break;
+ case TK_DO: DoWhileStatement(); break;
+ case TK_FOR: ForStatement(); break;
+ case TK_FOREACH: ForEachStatement(); break;
+ case TK_SWITCH: SwitchStatement(); break;
+ case TK_LOCAL: LocalDeclStatement(); break;
+ case TK_RETURN:
+ case TK_YIELD: {
+ SQOpcode op;
+ if(_token == TK_RETURN) {
+ op = _OP_RETURN;
+
+ }
+ else {
+ op = _OP_YIELD;
+ _fs->_bgenerator = true;
+ }
+ Lex();
+ if(!IsEndOfStatement()) {
+ SQInteger retexp = _fs->GetCurrentPos()+1;
+ CommaExpr();
+ if(op == _OP_RETURN && _fs->_traps > 0)
+ _fs->AddInstruction(_OP_POPTRAP, _fs->_traps, 0);
+ _fs->_returnexp = retexp;
+ _fs->AddInstruction(op, 1, _fs->PopTarget());
+ }
+ else{
+ if(op == _OP_RETURN && _fs->_traps > 0)
+ _fs->AddInstruction(_OP_POPTRAP, _fs->_traps ,0);
+ _fs->_returnexp = -1;
+ _fs->AddInstruction(op, 0xFF);
+ }
+ break;}
+ case TK_BREAK:
+ if(_fs->_breaktargets.size() <= 0)Error(_SC("'break' has to be in a loop block"));
+ if(_fs->_breaktargets.top() > 0){
+ _fs->AddInstruction(_OP_POPTRAP, _fs->_breaktargets.top(), 0);
+ }
+ _fs->AddInstruction(_OP_JMP, 0, -1234);
+ _fs->_unresolvedbreaks.push_back(_fs->GetCurrentPos());
+ Lex();
+ break;
+ case TK_CONTINUE:
+ if(_fs->_continuetargets.size() <= 0)Error(_SC("'continue' has to be in a loop block"));
+ if(_fs->_continuetargets.top() > 0) {
+ _fs->AddInstruction(_OP_POPTRAP, _fs->_continuetargets.top(), 0);
+ }
+ _fs->AddInstruction(_OP_JMP, 0, -1234);
+ _fs->_unresolvedcontinues.push_back(_fs->GetCurrentPos());
+ Lex();
+ break;
+ case TK_FUNCTION:
+ FunctionStatement();
+ break;
+ case TK_CLASS:
+ ClassStatement();
+ break;
+ case TK_ENUM:
+ EnumStatement();
+ break;
+ case _SC('{'):{
+ SQInteger stacksize = _fs->GetStackSize();
+ Lex();
+ Statements();
+ Expect(_SC('}'));
+ _fs->SetStackSize(stacksize);
+ }
+ break;
+ case TK_TRY:
+ TryCatchStatement();
+ break;
+ case TK_THROW:
+ Lex();
+ CommaExpr();
+ _fs->AddInstruction(_OP_THROW, _fs->PopTarget());
+ break;
+ case TK_CONST:
+ {
+ Lex();
+ SQObject id = Expect(TK_IDENTIFIER);
+ Expect('=');
+ SQObject val = ExpectScalar();
+ OptionalSemicolon();
+ SQTable *enums = _table(_ss(_vm)->_consts);
+ SQObjectPtr strongid = id;
+ enums->NewSlot(strongid,SQObjectPtr(val));
+ strongid.Null();
+ }
+ break;
+ default:
+ CommaExpr();
+ _fs->PopTarget();
+ break;
+ }
+ _fs->SnoozeOpt();
+ }
+ void EmitDerefOp(SQOpcode op)
+ {
+ SQInteger val = _fs->PopTarget();
+ SQInteger key = _fs->PopTarget();
+ SQInteger src = _fs->PopTarget();
+ _fs->AddInstruction(op,_fs->PushTarget(),src,key,val);
+ }
+ void Emit2ArgsOP(SQOpcode op, SQInteger p3 = 0)
+ {
+ SQInteger p2 = _fs->PopTarget(); //src in OP_GET
+ SQInteger p1 = _fs->PopTarget(); //key in OP_GET
+ _fs->AddInstruction(op,_fs->PushTarget(), p1, p2, p3);
+ }
+ void EmitCompoundArith(SQInteger tok,bool deref)
+ {
+ SQInteger oper;
+ switch(tok){
+ case TK_MINUSEQ: oper = '-'; break;
+ case TK_PLUSEQ: oper = '+'; break;
+ case TK_MULEQ: oper = '*'; break;
+ case TK_DIVEQ: oper = '/'; break;
+ case TK_MODEQ: oper = '%'; break;
+ default: oper = 0; //shut up compiler
+ assert(0); break;
+ };
+ if(deref) {
+ SQInteger val = _fs->PopTarget();
+ SQInteger key = _fs->PopTarget();
+ SQInteger src = _fs->PopTarget();
+ //mixes dest obj and source val in the arg1(hack?)
+ _fs->AddInstruction(_OP_COMPARITH,_fs->PushTarget(),(src<<16)|val,key,oper);
+ }
+ else {
+ Emit2ArgsOP(_OP_COMPARITHL, oper);
+ }
+ }
+ void CommaExpr()
+ {
+ for(Expression();_token == ',';_fs->PopTarget(), Lex(), CommaExpr());
+ }
+ ExpState Expression(bool funcarg = false)
+ {
+ PushExpState();
+ _exst._class_or_delete = false;
+ _exst._funcarg = funcarg;
+ LogicalOrExp();
+ switch(_token) {
+ case _SC('='):
+ case TK_NEWSLOT:
+ case TK_MINUSEQ:
+ case TK_PLUSEQ:
+ case TK_MULEQ:
+ case TK_DIVEQ:
+ case TK_MODEQ:
+ {
+ SQInteger op = _token;
+ SQInteger ds = _exst._deref;
+ bool freevar = _exst._freevar;
+ if(ds == DEREF_NO_DEREF) Error(_SC("can't assign expression"));
+ Lex(); Expression();
+
+ switch(op){
+ case TK_NEWSLOT:
+ if(freevar) Error(_SC("free variables cannot be modified"));
+ if(ds == DEREF_FIELD)
+ EmitDerefOp(_OP_NEWSLOT);
+ else //if _derefstate != DEREF_NO_DEREF && DEREF_FIELD so is the index of a local
+ Error(_SC("can't 'create' a local slot"));
+ break;
+ case _SC('='): //ASSIGN
+ if(freevar) Error(_SC("free variables cannot be modified"));
+ if(ds == DEREF_FIELD)
+ EmitDerefOp(_OP_SET);
+ else {//if _derefstate != DEREF_NO_DEREF && DEREF_FIELD so is the index of a local
+ SQInteger p2 = _fs->PopTarget(); //src in OP_GET
+ SQInteger p1 = _fs->TopTarget(); //key in OP_GET
+ _fs->AddInstruction(_OP_MOVE, p1, p2);
+ }
+ break;
+ case TK_MINUSEQ:
+ case TK_PLUSEQ:
+ case TK_MULEQ:
+ case TK_DIVEQ:
+ case TK_MODEQ:
+ EmitCompoundArith(op,ds == DEREF_FIELD);
+ break;
+ }
+ }
+ break;
+ case _SC('?'): {
+ Lex();
+ _fs->AddInstruction(_OP_JZ, _fs->PopTarget());
+ SQInteger jzpos = _fs->GetCurrentPos();
+ SQInteger trg = _fs->PushTarget();
+ Expression();
+ SQInteger first_exp = _fs->PopTarget();
+ if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp);
+ SQInteger endfirstexp = _fs->GetCurrentPos();
+ _fs->AddInstruction(_OP_JMP, 0, 0);
+ Expect(_SC(':'));
+ SQInteger jmppos = _fs->GetCurrentPos();
+ Expression();
+ SQInteger second_exp = _fs->PopTarget();
+ if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp);
+ _fs->SetIntructionParam(jmppos, 1, _fs->GetCurrentPos() - jmppos);
+ _fs->SetIntructionParam(jzpos, 1, endfirstexp - jzpos + 1);
+ _fs->SnoozeOpt();
+ }
+ break;
+ }
+ return PopExpState();
+ }
+ void BIN_EXP(SQOpcode op, void (SQCompiler::*f)(void),SQInteger op3 = 0)
+ {
+ Lex(); (this->*f)();
+ SQInteger op1 = _fs->PopTarget();SQInteger op2 = _fs->PopTarget();
+ _fs->AddInstruction(op, _fs->PushTarget(), op1, op2, op3);
+ }
+ void LogicalOrExp()
+ {
+ LogicalAndExp();
+ for(;;) if(_token == TK_OR) {
+ SQInteger first_exp = _fs->PopTarget();
+ SQInteger trg = _fs->PushTarget();
+ _fs->AddInstruction(_OP_OR, trg, 0, first_exp, 0);
+ SQInteger jpos = _fs->GetCurrentPos();
+ if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp);
+ Lex(); LogicalOrExp();
+ _fs->SnoozeOpt();
+ SQInteger second_exp = _fs->PopTarget();
+ if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp);
+ _fs->SnoozeOpt();
+ _fs->SetIntructionParam(jpos, 1, (_fs->GetCurrentPos() - jpos));
+ break;
+ }else return;
+ }
+ void LogicalAndExp()
+ {
+ BitwiseOrExp();
+ for(;;) switch(_token) {
+ case TK_AND: {
+ SQInteger first_exp = _fs->PopTarget();
+ SQInteger trg = _fs->PushTarget();
+ _fs->AddInstruction(_OP_AND, trg, 0, first_exp, 0);
+ SQInteger jpos = _fs->GetCurrentPos();
+ if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp);
+ Lex(); LogicalAndExp();
+ _fs->SnoozeOpt();
+ SQInteger second_exp = _fs->PopTarget();
+ if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp);
+ _fs->SnoozeOpt();
+ _fs->SetIntructionParam(jpos, 1, (_fs->GetCurrentPos() - jpos));
+ break;
+ }
+ case TK_IN: BIN_EXP(_OP_EXISTS, &SQCompiler::BitwiseOrExp); break;
+ case TK_INSTANCEOF: BIN_EXP(_OP_INSTANCEOF, &SQCompiler::BitwiseOrExp); break;
+ default:
+ return;
+ }
+ }
+ void BitwiseOrExp()
+ {
+ BitwiseXorExp();
+ for(;;) if(_token == _SC('|'))
+ {BIN_EXP(_OP_BITW, &SQCompiler::BitwiseXorExp,BW_OR);
+ }else return;
+ }
+ void BitwiseXorExp()
+ {
+ BitwiseAndExp();
+ for(;;) if(_token == _SC('^'))
+ {BIN_EXP(_OP_BITW, &SQCompiler::BitwiseAndExp,BW_XOR);
+ }else return;
+ }
+ void BitwiseAndExp()
+ {
+ CompExp();
+ for(;;) if(_token == _SC('&'))
+ {BIN_EXP(_OP_BITW, &SQCompiler::CompExp,BW_AND);
+ }else return;
+ }
+ void CompExp()
+ {
+ ShiftExp();
+ for(;;) switch(_token) {
+ case TK_EQ: BIN_EXP(_OP_EQ, &SQCompiler::ShiftExp); break;
+ case _SC('>'): BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_G); break;
+ case _SC('<'): BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_L); break;
+ case TK_GE: BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_GE); break;
+ case TK_LE: BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_LE); break;
+ case TK_NE: BIN_EXP(_OP_NE, &SQCompiler::ShiftExp); break;
+ default: return;
+ }
+ }
+ void ShiftExp()
+ {
+ PlusExp();
+ for(;;) switch(_token) {
+ case TK_USHIFTR: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_USHIFTR); break;
+ case TK_SHIFTL: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_SHIFTL); break;
+ case TK_SHIFTR: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_SHIFTR); break;
+ default: return;
+ }
+ }
+ void PlusExp()
+ {
+ MultExp();
+ for(;;) switch(_token) {
+ case _SC('+'): case _SC('-'):
+ BIN_EXP(_OP_ARITH, &SQCompiler::MultExp,_token); break;
+ default: return;
+ }
+ }
+
+ void MultExp()
+ {
+ PrefixedExpr();
+ for(;;) switch(_token) {
+ case _SC('*'): case _SC('/'): case _SC('%'):
+ BIN_EXP(_OP_ARITH, &SQCompiler::PrefixedExpr,_token); break;
+ default: return;
+ }
+ }
+ //if 'pos' != -1 the previous variable is a local variable
+ void PrefixedExpr()
+ {
+ SQInteger pos = Factor();
+ for(;;) {
+ switch(_token) {
+ case _SC('.'): {
+ pos = -1;
+ Lex();
+ if(_token == TK_PARENT) {
+ Lex();
+ if(!NeedGet())
+ Error(_SC("parent cannot be set"));
+ SQInteger src = _fs->PopTarget();
+ _fs->AddInstruction(_OP_GETPARENT, _fs->PushTarget(), src);
+ }
+ else {
+ _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(Expect(TK_IDENTIFIER)));
+ if(NeedGet()) Emit2ArgsOP(_OP_GET);
+ }
+ _exst._deref = DEREF_FIELD;
+ _exst._freevar = false;
+ }
+ break;
+ case _SC('['):
+ if(_lex._prevtoken == _SC('\n')) Error(_SC("cannot brake deref/or comma needed after [exp]=exp slot declaration"));
+ Lex(); Expression(); Expect(_SC(']'));
+ pos = -1;
+ if(NeedGet()) Emit2ArgsOP(_OP_GET);
+ _exst._deref = DEREF_FIELD;
+ _exst._freevar = false;
+ break;
+ case TK_MINUSMINUS:
+ case TK_PLUSPLUS:
+ if(_exst._deref != DEREF_NO_DEREF && !IsEndOfStatement()) {
+ SQInteger tok = _token; Lex();
+ if(pos < 0)
+ Emit2ArgsOP(_OP_PINC,tok == TK_MINUSMINUS?-1:1);
+ else {//if _derefstate != DEREF_NO_DEREF && DEREF_FIELD so is the index of a local
+ SQInteger src = _fs->PopTarget();
+ _fs->AddInstruction(_OP_PINCL, _fs->PushTarget(), src, 0, tok == TK_MINUSMINUS?-1:1);
+ }
+
+ }
+ return;
+ break;
+ case _SC('('):
+ {
+ if(_exst._deref != DEREF_NO_DEREF) {
+ if(pos<0) {
+ SQInteger key = _fs->PopTarget(); //key
+ SQInteger table = _fs->PopTarget(); //table etc...
+ SQInteger closure = _fs->PushTarget();
+ SQInteger ttarget = _fs->PushTarget();
+ _fs->AddInstruction(_OP_PREPCALL, closure, key, table, ttarget);
+ }
+ else{
+ _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), 0);
+ }
+ }
+ else
+ _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), 0);
+ _exst._deref = DEREF_NO_DEREF;
+ Lex();
+ FunctionCallArgs();
+ }
+ break;
+ default: return;
+ }
+ }
+ }
+ SQInteger Factor()
+ {
+ switch(_token)
+ {
+ case TK_STRING_LITERAL: {
+ //SQObjectPtr id(SQString::Create(_ss(_vm), _lex._svalue,_lex._longstr.size()-1));
+ _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(_fs->CreateString(_lex._svalue,_lex._longstr.size()-1)));
+ Lex();
+ }
+ break;
+ case TK_VARGC: Lex(); _fs->AddInstruction(_OP_VARGC, _fs->PushTarget()); break;
+ case TK_VARGV: { Lex();
+ Expect(_SC('['));
+ Expression();
+ Expect(_SC(']'));
+ SQInteger src = _fs->PopTarget();
+ _fs->AddInstruction(_OP_GETVARGV, _fs->PushTarget(), src);
+ }
+ break;
+ case TK_IDENTIFIER:
+ case TK_CONSTRUCTOR:
+ case TK_THIS:{
+ _exst._freevar = false;
+ SQObject id;
+ SQObject constant;
+ switch(_token) {
+ case TK_IDENTIFIER: id = _fs->CreateString(_lex._svalue); break;
+ case TK_THIS: id = _fs->CreateString(_SC("this")); break;
+ case TK_CONSTRUCTOR: id = _fs->CreateString(_SC("constructor")); break;
+ }
+ SQInteger pos = -1;
+ Lex();
+ if((pos = _fs->GetLocalVariable(id)) == -1) {
+ //checks if is a free variable
+ if((pos = _fs->GetOuterVariable(id)) != -1) {
+ _exst._deref = _fs->PushTarget();
+ _fs->AddInstruction(_OP_LOADFREEVAR, _exst._deref ,pos);
+ _exst._freevar = true;
+ }
+ else if(_fs->IsConstant(id,constant)) { //line 634
+ SQObjectPtr constval;
+ SQObject constid;
+ if(type(constant) == OT_TABLE) {
+ Expect('.'); constid = Expect(TK_IDENTIFIER);
+ if(!_table(constant)->Get(constid,constval)) {
+ constval.Null();
+ Error(_SC("invalid constant [%s.%s]"), _stringval(id),_stringval(constid));
+ }
+ }
+ else {
+ constval = constant;
+ }
+ _exst._deref = _fs->PushTarget();
+ SQObjectType ctype = type(constval);
+ if(ctype == OT_INTEGER && (_integer(constval) & (~0x7FFFFFFF)) == 0) {
+ _fs->AddInstruction(_OP_LOADINT, _exst._deref,_integer(constval));
+ }
+ else if(ctype == OT_FLOAT && sizeof(SQFloat) == sizeof(SQInt32)) {
+ SQFloat f = _float(constval);
+ _fs->AddInstruction(_OP_LOADFLOAT, _exst._deref,*((SQInt32 *)&f));
+ }
+ else {
+ _fs->AddInstruction(_OP_LOAD, _exst._deref, _fs->GetConstant(constval));
+ }
+
+ _exst._freevar = true;
+ }
+ else {
+ _fs->PushTarget(0);
+ _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));
+ if(NeedGet()) Emit2ArgsOP(_OP_GET);
+ _exst._deref = DEREF_FIELD;
+ }
+ }
+
+ else{
+ _fs->PushTarget(pos);
+ _exst._deref = pos;
+ }
+ return _exst._deref;
+ }
+ break;
+ case TK_PARENT: Lex();_fs->AddInstruction(_OP_GETPARENT, _fs->PushTarget(), 0); break;
+ case TK_DOUBLE_COLON: // "::"
+ _fs->AddInstruction(_OP_LOADROOTTABLE, _fs->PushTarget());
+ _exst._deref = DEREF_FIELD;
+ _token = _SC('.'); //hack
+ return -1;
+ break;
+ case TK_NULL:
+ _fs->AddInstruction(_OP_LOADNULLS, _fs->PushTarget(),1);
+ Lex();
+ break;
+ case TK_INTEGER: {
+ if((_lex._nvalue & (~0x7FFFFFFF)) == 0) { //does it fit in 32 bits?
+ _fs->AddInstruction(_OP_LOADINT, _fs->PushTarget(),_lex._nvalue);
+ }
+ else {
+ _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetNumericConstant(_lex._nvalue));
+ }
+ Lex();
+ }
+ break;
+ case TK_FLOAT:
+ if(sizeof(SQFloat) == sizeof(SQInt32)) {
+ _fs->AddInstruction(_OP_LOADFLOAT, _fs->PushTarget(),*((SQInt32 *)&_lex._fvalue));
+ }
+ else {
+ _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetNumericConstant(_lex._fvalue));
+ }
+ Lex();
+ break;
+ case TK_TRUE: case TK_FALSE:
+ _fs->AddInstruction(_OP_LOADBOOL, _fs->PushTarget(),_token == TK_TRUE?1:0);
+ Lex();
+ break;
+ case _SC('['): {
+ _fs->AddInstruction(_OP_NEWARRAY, _fs->PushTarget());
+ SQInteger apos = _fs->GetCurrentPos(),key = 0;
+ Lex();
+ while(_token != _SC(']')) {
+ Expression();
+ if(_token == _SC(',')) Lex();
+ SQInteger val = _fs->PopTarget();
+ SQInteger array = _fs->TopTarget();
+ _fs->AddInstruction(_OP_APPENDARRAY, array, val);
+ key++;
+ }
+ _fs->SetIntructionParam(apos, 1, key);
+ Lex();
+ }
+ break;
+ case _SC('{'):{
+ _fs->AddInstruction(_OP_NEWTABLE, _fs->PushTarget());
+ Lex();ParseTableOrClass(_SC(','));
+ }
+ break;
+ case TK_FUNCTION: FunctionExp(_token);break;
+ case TK_CLASS: Lex(); ClassExp();break;
+ case _SC('-'): UnaryOP(_OP_NEG); break;
+ case _SC('!'): UnaryOP(_OP_NOT); break;
+ case _SC('~'): UnaryOP(_OP_BWNOT); break;
+ case TK_TYPEOF : UnaryOP(_OP_TYPEOF); break;
+ case TK_RESUME : UnaryOP(_OP_RESUME); break;
+ case TK_CLONE : UnaryOP(_OP_CLONE); break;
+ case TK_MINUSMINUS :
+ case TK_PLUSPLUS :PrefixIncDec(_token); break;
+ case TK_DELETE : DeleteExpr(); break;
+ case TK_DELEGATE : DelegateExpr(); break;
+ case _SC('('): Lex(); CommaExpr(); Expect(_SC(')'));
+ break;
+ default: Error(_SC("expression expected"));
+ }
+ return -1;
+ }
+ void UnaryOP(SQOpcode op)
+ {
+ Lex(); PrefixedExpr();
+ SQInteger src = _fs->PopTarget();
+ _fs->AddInstruction(op, _fs->PushTarget(), src);
+ }
+ bool NeedGet()
+ {
+ switch(_token) {
+ case _SC('='): case _SC('('): case TK_NEWSLOT: case TK_PLUSPLUS: case TK_MINUSMINUS:
+ case TK_PLUSEQ: case TK_MINUSEQ: case TK_MULEQ: case TK_DIVEQ: case TK_MODEQ:
+ return false;
+ }
+ return (!_exst._class_or_delete) || (_exst._class_or_delete && (_token == _SC('.') || _token == _SC('[')));
+ }
+
+ void FunctionCallArgs()
+ {
+ SQInteger nargs = 1;//this
+ while(_token != _SC(')')) {
+ Expression(true);
+ MoveIfCurrentTargetIsLocal();
+ nargs++;
+ if(_token == _SC(',')){
+ Lex();
+ if(_token == ')') Error(_SC("expression expected, found ')'"));
+ }
+ }
+ Lex();
+ for(SQInteger i = 0; i < (nargs - 1); i++) _fs->PopTarget();
+ SQInteger stackbase = _fs->PopTarget();
+ SQInteger closure = _fs->PopTarget();
+ _fs->AddInstruction(_OP_CALL, _fs->PushTarget(), closure, stackbase, nargs);
+ }
+ void ParseTableOrClass(SQInteger separator,SQInteger terminator = '}')
+ {
+ SQInteger tpos = _fs->GetCurrentPos(),nkeys = 0;
+
+ while(_token != terminator) {
+ bool hasattrs = false;
+ bool isstatic = false;
+ //check if is an attribute
+ if(separator == ';') {
+ if(_token == TK_ATTR_OPEN) {
+ _fs->AddInstruction(_OP_NEWTABLE, _fs->PushTarget()); Lex();
+ ParseTableOrClass(',',TK_ATTR_CLOSE);
+ hasattrs = true;
+ }
+ if(_token == TK_STATIC) {
+ isstatic = true;
+ Lex();
+ }
+ }
+ switch(_token) {
+ case TK_FUNCTION:
+ case TK_CONSTRUCTOR:{
+ SQInteger tk = _token;
+ Lex();
+ SQObject id = tk == TK_FUNCTION ? Expect(TK_IDENTIFIER) : _fs->CreateString(_SC("constructor"));
+ Expect(_SC('('));
+ _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));
+ CreateFunction(id);
+ _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, 0);
+ }
+ break;
+ case _SC('['):
+ Lex(); CommaExpr(); Expect(_SC(']'));
+ Expect(_SC('=')); Expression();
+ break;
+ default :
+ _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(Expect(TK_IDENTIFIER)));
+ Expect(_SC('=')); Expression();
+ }
+
+ if(_token == separator) Lex();//optional comma/semicolon
+ nkeys++;
+ SQInteger val = _fs->PopTarget();
+ SQInteger key = _fs->PopTarget();
+ SQInteger attrs = hasattrs ? _fs->PopTarget():-1;
+ assert(hasattrs && attrs == key-1 || !hasattrs);
+ unsigned char flags = (hasattrs?NEW_SLOT_ATTRIBUTES_FLAG:0)|(isstatic?NEW_SLOT_STATIC_FLAG:0);
+ SQInteger table = _fs->TopTarget(); //<<BECAUSE OF THIS NO COMMON EMIT FUNC IS POSSIBLE
+ _fs->AddInstruction(_OP_NEWSLOTA, flags, table, key, val);
+ //_fs->PopTarget();
+ }
+ if(separator == _SC(',')) //hack recognizes a table from the separator
+ _fs->SetIntructionParam(tpos, 1, nkeys);
+ Lex();
+ }
+ void LocalDeclStatement()
+ {
+ SQObject varname;
+ do {
+ Lex(); varname = Expect(TK_IDENTIFIER);
+ if(_token == _SC('=')) {
+ Lex(); Expression();
+ SQInteger src = _fs->PopTarget();
+ SQInteger dest = _fs->PushTarget();
+ if(dest != src) _fs->AddInstruction(_OP_MOVE, dest, src);
+ }
+ else{
+ _fs->AddInstruction(_OP_LOADNULLS, _fs->PushTarget(),1);
+ }
+ _fs->PopTarget();
+ _fs->PushLocalVariable(varname);
+
+ } while(_token == _SC(','));
+ }
+ void IfStatement()
+ {
+ SQInteger jmppos;
+ bool haselse = false;
+ Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')'));
+ _fs->AddInstruction(_OP_JZ, _fs->PopTarget());
+ SQInteger jnepos = _fs->GetCurrentPos();
+ SQInteger stacksize = _fs->GetStackSize();
+
+ Statement();
+ //
+ if(_token != _SC('}') && _token != TK_ELSE) OptionalSemicolon();
+
+ CleanStack(stacksize);
+ SQInteger endifblock = _fs->GetCurrentPos();
+ if(_token == TK_ELSE){
+ haselse = true;
+ stacksize = _fs->GetStackSize();
+ _fs->AddInstruction(_OP_JMP);
+ jmppos = _fs->GetCurrentPos();
+ Lex();
+ Statement(); OptionalSemicolon();
+ CleanStack(stacksize);
+ _fs->SetIntructionParam(jmppos, 1, _fs->GetCurrentPos() - jmppos);
+ }
+ _fs->SetIntructionParam(jnepos, 1, endifblock - jnepos + (haselse?1:0));
+ }
+ void WhileStatement()
+ {
+ SQInteger jzpos, jmppos;
+ SQInteger stacksize = _fs->GetStackSize();
+ jmppos = _fs->GetCurrentPos();
+ Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')'));
+
+ BEGIN_BREAKBLE_BLOCK();
+ _fs->AddInstruction(_OP_JZ, _fs->PopTarget());
+ jzpos = _fs->GetCurrentPos();
+ stacksize = _fs->GetStackSize();
+
+ Statement();
+
+ CleanStack(stacksize);
+ _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1);
+ _fs->SetIntructionParam(jzpos, 1, _fs->GetCurrentPos() - jzpos);
+
+ END_BREAKBLE_BLOCK(jmppos);
+ }
+ void DoWhileStatement()
+ {
+ Lex();
+ SQInteger jzpos = _fs->GetCurrentPos();
+ SQInteger stacksize = _fs->GetStackSize();
+ BEGIN_BREAKBLE_BLOCK()
+ Statement();
+ CleanStack(stacksize);
+ Expect(TK_WHILE);
+ SQInteger continuetrg = _fs->GetCurrentPos();
+ Expect(_SC('(')); CommaExpr(); Expect(_SC(')'));
+ _fs->AddInstruction(_OP_JNZ, _fs->PopTarget(), jzpos - _fs->GetCurrentPos() - 1);
+ END_BREAKBLE_BLOCK(continuetrg);
+ }
+ void ForStatement()
+ {
+ Lex();
+ SQInteger stacksize = _fs->GetStackSize();
+ Expect(_SC('('));
+ if(_token == TK_LOCAL) LocalDeclStatement();
+ else if(_token != _SC(';')){
+ CommaExpr();
+ _fs->PopTarget();
+ }
+ Expect(_SC(';'));
+ _fs->SnoozeOpt();
+ SQInteger jmppos = _fs->GetCurrentPos();
+ SQInteger jzpos = -1;
+ if(_token != _SC(';')) { CommaExpr(); _fs->AddInstruction(_OP_JZ, _fs->PopTarget()); jzpos = _fs->GetCurrentPos(); }
+ Expect(_SC(';'));
+ _fs->SnoozeOpt();
+ SQInteger expstart = _fs->GetCurrentPos() + 1;
+ if(_token != _SC(')')) {
+ CommaExpr();
+ _fs->PopTarget();
+ }
+ Expect(_SC(')'));
+ _fs->SnoozeOpt();
+ SQInteger expend = _fs->GetCurrentPos();
+ SQInteger expsize = (expend - expstart) + 1;
+ SQInstructionVec exp;
+ if(expsize > 0) {
+ for(SQInteger i = 0; i < expsize; i++)
+ exp.push_back(_fs->GetInstruction(expstart + i));
+ _fs->PopInstructions(expsize);
+ }
+ BEGIN_BREAKBLE_BLOCK()
+ Statement();
+ SQInteger continuetrg = _fs->GetCurrentPos();
+ if(expsize > 0) {
+ for(SQInteger i = 0; i < expsize; i++)
+ _fs->AddInstruction(exp[i]);
+ }
+ _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1, 0);
+ if(jzpos> 0) _fs->SetIntructionParam(jzpos, 1, _fs->GetCurrentPos() - jzpos);
+ CleanStack(stacksize);
+
+ END_BREAKBLE_BLOCK(continuetrg);
+ }
+ void ForEachStatement()
+ {
+ SQObject idxname, valname;
+ Lex(); Expect(_SC('(')); valname = Expect(TK_IDENTIFIER);
+ if(_token == _SC(',')) {
+ idxname = valname;
+ Lex(); valname = Expect(TK_IDENTIFIER);
+ }
+ else{
+ idxname = _fs->CreateString(_SC("@INDEX@"));
+ }
+ Expect(TK_IN);
+
+ //save the stack size
+ SQInteger stacksize = _fs->GetStackSize();
+ //put the table in the stack(evaluate the table expression)
+ Expression(); Expect(_SC(')'));
+ SQInteger container = _fs->TopTarget();
+ //push the index local var
+ SQInteger indexpos = _fs->PushLocalVariable(idxname);
+ _fs->AddInstruction(_OP_LOADNULLS, indexpos,1);
+ //push the value local var
+ SQInteger valuepos = _fs->PushLocalVariable(valname);
+ _fs->AddInstruction(_OP_LOADNULLS, valuepos,1);
+ //push reference index
+ SQInteger itrpos = _fs->PushLocalVariable(_fs->CreateString(_SC("@ITERATOR@"))); //use invalid id to make it inaccessible
+ _fs->AddInstruction(_OP_LOADNULLS, itrpos,1);
+ SQInteger jmppos = _fs->GetCurrentPos();
+ _fs->AddInstruction(_OP_FOREACH, container, 0, indexpos);
+ SQInteger foreachpos = _fs->GetCurrentPos();
+ _fs->AddInstruction(_OP_POSTFOREACH, container, 0, indexpos);
+ //generate the statement code
+ BEGIN_BREAKBLE_BLOCK()
+ Statement();
+ _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1);
+ _fs->SetIntructionParam(foreachpos, 1, _fs->GetCurrentPos() - foreachpos);
+ _fs->SetIntructionParam(foreachpos + 1, 1, _fs->GetCurrentPos() - foreachpos);
+ //restore the local variable stack(remove index,val and ref idx)
+ CleanStack(stacksize);
+ END_BREAKBLE_BLOCK(foreachpos - 1);
+ }
+ void SwitchStatement()
+ {
+ Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')'));
+ Expect(_SC('{'));
+ SQInteger expr = _fs->TopTarget();
+ bool bfirst = true;
+ SQInteger tonextcondjmp = -1;
+ SQInteger skipcondjmp = -1;
+ SQInteger __nbreaks__ = _fs->_unresolvedbreaks.size();
+ _fs->_breaktargets.push_back(0);
+ while(_token == TK_CASE) {
+ //_fs->AddLineInfos(_lex._currentline, _lineinfo); think about this one
+ if(!bfirst) {
+ _fs->AddInstruction(_OP_JMP, 0, 0);
+ skipcondjmp = _fs->GetCurrentPos();
+ _fs->SetIntructionParam(tonextcondjmp, 1, _fs->GetCurrentPos() - tonextcondjmp);
+ }
+ //condition
+ Lex(); Expression(); Expect(_SC(':'));
+ SQInteger trg = _fs->PopTarget();
+ _fs->AddInstruction(_OP_EQ, trg, trg, expr);
+ _fs->AddInstruction(_OP_JZ, trg, 0);
+ //end condition
+ if(skipcondjmp != -1) {
+ _fs->SetIntructionParam(skipcondjmp, 1, (_fs->GetCurrentPos() - skipcondjmp));
+ }
+ tonextcondjmp = _fs->GetCurrentPos();
+ SQInteger stacksize = _fs->GetStackSize();
+ Statements();
+ _fs->SetStackSize(stacksize);
+ bfirst = false;
+ }
+ if(tonextcondjmp != -1)
+ _fs->SetIntructionParam(tonextcondjmp, 1, _fs->GetCurrentPos() - tonextcondjmp);
+ if(_token == TK_DEFAULT) {
+ // _fs->AddLineInfos(_lex._currentline, _lineinfo);
+ Lex(); Expect(_SC(':'));
+ SQInteger stacksize = _fs->GetStackSize();
+ Statements();
+ _fs->SetStackSize(stacksize);
+ }
+ Expect(_SC('}'));
+ _fs->PopTarget();
+ __nbreaks__ = _fs->_unresolvedbreaks.size() - __nbreaks__;
+ if(__nbreaks__ > 0)ResolveBreaks(_fs, __nbreaks__);
+ _fs->_breaktargets.pop_back();
+
+ }
+ void FunctionStatement()
+ {
+ SQObject id;
+ Lex(); id = Expect(TK_IDENTIFIER);
+ _fs->PushTarget(0);
+ _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));
+ if(_token == TK_DOUBLE_COLON) Emit2ArgsOP(_OP_GET);
+
+ while(_token == TK_DOUBLE_COLON) {
+ Lex();
+ id = Expect(TK_IDENTIFIER);
+ _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));
+ if(_token == TK_DOUBLE_COLON) Emit2ArgsOP(_OP_GET);
+ }
+ Expect(_SC('('));
+ CreateFunction(id);
+ _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, 0);
+ EmitDerefOp(_OP_NEWSLOT);
+ _fs->PopTarget();
+ }
+ void ClassStatement()
+ {
+ ExpState es;
+ Lex(); PushExpState();
+ _exst._class_or_delete = true;
+ _exst._funcarg = false;
+ PrefixedExpr();
+ es = PopExpState();
+ if(es._deref == DEREF_NO_DEREF) Error(_SC("invalid class name"));
+ if(es._deref == DEREF_FIELD) {
+ ClassExp();
+ EmitDerefOp(_OP_NEWSLOT);
+ _fs->PopTarget();
+ }
+ else Error(_SC("cannot create a class in a local with the syntax(class <local>)"));
+ }
+ SQObject ExpectScalar()
+ {
+ SQObject val;
+ switch(_token) {
+ case TK_INTEGER:
+ val._type = OT_INTEGER;
+ val._unVal.nInteger = _lex._nvalue;
+ break;
+ case TK_FLOAT:
+ val._type = OT_FLOAT;
+ val._unVal.fFloat = _lex._fvalue;
+ break;
+ case TK_STRING_LITERAL:
+ val = _fs->CreateString(_lex._svalue,_lex._longstr.size()-1);
+ break;
+ case '-':
+ Lex();
+ switch(_token)
+ {
+ case TK_INTEGER:
+ val._type = OT_INTEGER;
+ val._unVal.nInteger = -_lex._nvalue;
+ break;
+ case TK_FLOAT:
+ val._type = OT_FLOAT;
+ val._unVal.fFloat = -_lex._fvalue;
+ break;
+ default:
+ Error(_SC("scalar expected : integer,float"));
+ }
+ break;
+ default:
+ Error(_SC("scalar expected : integer,float or string"));
+ }
+ Lex();
+ return val;
+ }
+ void EnumStatement()
+ {
+
+ Lex();
+ SQObject id = Expect(TK_IDENTIFIER);
+ Expect(_SC('{'));
+
+ SQObject table = _fs->CreateTable();
+ SQInteger nval = 0;
+ while(_token != _SC('}')) {
+ SQObject key = Expect(TK_IDENTIFIER);
+ SQObject val;
+ if(_token == _SC('=')) {
+ Lex();
+ val = ExpectScalar();
+ }
+ else {
+ val._type = OT_INTEGER;
+ val._unVal.nInteger = nval++;
+ }
+ _table(table)->NewSlot(SQObjectPtr(key),SQObjectPtr(val));
+ if(_token == ',') Lex();
+ }
+ SQTable *enums = _table(_ss(_vm)->_consts);
+ SQObjectPtr strongid = id;
+ /*SQObjectPtr dummy;
+ if(enums->Get(strongid,dummy)) {
+ dummy.Null(); strongid.Null();
+ Error(_SC("enumeration already exists"));
+ }*/
+ enums->NewSlot(SQObjectPtr(strongid),SQObjectPtr(table));
+ strongid.Null();
+ Lex();
+
+ }
+ void TryCatchStatement()
+ {
+ SQObject exid;
+ Lex();
+ _fs->AddInstruction(_OP_PUSHTRAP,0,0);
+ _fs->_traps++;
+ if(_fs->_breaktargets.size()) _fs->_breaktargets.top()++;
+ if(_fs->_continuetargets.size()) _fs->_continuetargets.top()++;
+ SQInteger trappos = _fs->GetCurrentPos();
+ Statement();
+ _fs->_traps--;
+ _fs->AddInstruction(_OP_POPTRAP, 1, 0);
+ if(_fs->_breaktargets.size()) _fs->_breaktargets.top()--;
+ if(_fs->_continuetargets.size()) _fs->_continuetargets.top()--;
+ _fs->AddInstruction(_OP_JMP, 0, 0);
+ SQInteger jmppos = _fs->GetCurrentPos();
+ _fs->SetIntructionParam(trappos, 1, (_fs->GetCurrentPos() - trappos));
+ Expect(TK_CATCH); Expect(_SC('(')); exid = Expect(TK_IDENTIFIER); Expect(_SC(')'));
+ SQInteger stacksize = _fs->GetStackSize();
+ SQInteger ex_target = _fs->PushLocalVariable(exid);
+ _fs->SetIntructionParam(trappos, 0, ex_target);
+ Statement();
+ _fs->SetIntructionParams(jmppos, 0, (_fs->GetCurrentPos() - jmppos), 0);
+ CleanStack(stacksize);
+ }
+ void FunctionExp(SQInteger ftype)
+ {
+ Lex(); Expect(_SC('('));
+ CreateFunction(_null_);
+ _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, ftype == TK_FUNCTION?0:1);
+ }
+ void ClassExp()
+ {
+ SQInteger base = -1;
+ SQInteger attrs = -1;
+ if(_token == TK_EXTENDS) {
+ Lex(); Expression();
+ base = _fs->TopTarget();
+ }
+ if(_token == TK_ATTR_OPEN) {
+ Lex();
+ _fs->AddInstruction(_OP_NEWTABLE, _fs->PushTarget());
+ ParseTableOrClass(_SC(','),TK_ATTR_CLOSE);
+ attrs = _fs->TopTarget();
+ }
+ Expect(_SC('{'));
+ if(attrs != -1) _fs->PopTarget();
+ if(base != -1) _fs->PopTarget();
+ _fs->AddInstruction(_OP_CLASS, _fs->PushTarget(), base, attrs);
+ ParseTableOrClass(_SC(';'));
+ }
+ void DelegateExpr()
+ {
+ Lex(); CommaExpr();
+ Expect(_SC(':'));
+ CommaExpr();
+ SQInteger table = _fs->PopTarget(), delegate = _fs->PopTarget();
+ _fs->AddInstruction(_OP_DELEGATE, _fs->PushTarget(), table, delegate);
+ }
+ void DeleteExpr()
+ {
+ ExpState es;
+ Lex(); PushExpState();
+ _exst._class_or_delete = true;
+ _exst._funcarg = false;
+ PrefixedExpr();
+ es = PopExpState();
+ if(es._deref == DEREF_NO_DEREF) Error(_SC("can't delete an expression"));
+ if(es._deref == DEREF_FIELD) Emit2ArgsOP(_OP_DELETE);
+ else Error(_SC("cannot delete a local"));
+ }
+ void PrefixIncDec(SQInteger token)
+ {
+ ExpState es;
+ Lex(); PushExpState();
+ _exst._class_or_delete = true;
+ _exst._funcarg = false;
+ PrefixedExpr();
+ es = PopExpState();
+ if(es._deref == DEREF_FIELD) Emit2ArgsOP(_OP_INC,token == TK_MINUSMINUS?-1:1);
+ else {
+ SQInteger src = _fs->PopTarget();
+ _fs->AddInstruction(_OP_INCL, _fs->PushTarget(), src, 0, token == TK_MINUSMINUS?-1:1);
+ }
+ }
+ void CreateFunction(SQObject &name)
+ {
+
+ SQFuncState *funcstate = _fs->PushChildState(_ss(_vm));
+ funcstate->_name = name;
+ SQObject paramname;
+ funcstate->AddParameter(_fs->CreateString(_SC("this")));
+ funcstate->_sourcename = _sourcename;
+ SQInteger defparams = 0;
+ while(_token!=_SC(')')) {
+ if(_token == TK_VARPARAMS) {
+ if(defparams > 0) Error(_SC("function with default parameters cannot have variable number of parameters"));
+ funcstate->_varparams = true;
+ Lex();
+ if(_token != _SC(')')) Error(_SC("expected ')'"));
+ break;
+ }
+ else {
+ paramname = Expect(TK_IDENTIFIER);
+ funcstate->AddParameter(paramname);
+ if(_token == _SC('=')) {
+ Lex();
+ Expression();
+ funcstate->AddDefaultParam(_fs->TopTarget());
+ defparams++;
+ }
+ else {
+ if(defparams > 0) Error(_SC("expected '='"));
+ }
+ if(_token == _SC(',')) Lex();
+ else if(_token != _SC(')')) Error(_SC("expected ')' or ','"));
+ }
+ }
+ Expect(_SC(')'));
+ for(SQInteger n = 0; n < defparams; n++) {
+ _fs->PopTarget();
+ }
+ //outer values
+ if(_token == _SC(':')) {
+ Lex(); Expect(_SC('('));
+ while(_token != _SC(')')) {
+ paramname = Expect(TK_IDENTIFIER);
+ //outers are treated as implicit local variables
+ funcstate->AddOuterValue(paramname);
+ if(_token == _SC(',')) Lex();
+ else if(_token != _SC(')')) Error(_SC("expected ')' or ','"));
+ }
+ Lex();
+ }
+
+ SQFuncState *currchunk = _fs;
+ _fs = funcstate;
+ Statement();
+ funcstate->AddLineInfos(_lex._prevtoken == _SC('\n')?_lex._lasttokenline:_lex._currentline, _lineinfo, true);
+ funcstate->AddInstruction(_OP_RETURN, -1);
+ funcstate->SetStackSize(0);
+ //_fs->->_stacksize = _fs->_stacksize;
+ SQFunctionProto *func = funcstate->BuildProto();
+#ifdef _DEBUG_DUMP
+ funcstate->Dump(func);
+#endif
+ _fs = currchunk;
+ _fs->_functions.push_back(func);
+ _fs->PopChildState();
+ }
+ void CleanStack(SQInteger stacksize)
+ {
+ if(_fs->GetStackSize() != stacksize)
+ _fs->SetStackSize(stacksize);
+ }
+ void ResolveBreaks(SQFuncState *funcstate, SQInteger ntoresolve)
+ {
+ while(ntoresolve > 0) {
+ SQInteger pos = funcstate->_unresolvedbreaks.back();
+ funcstate->_unresolvedbreaks.pop_back();
+ //set the jmp instruction
+ funcstate->SetIntructionParams(pos, 0, funcstate->GetCurrentPos() - pos, 0);
+ ntoresolve--;
+ }
+ }
+ void ResolveContinues(SQFuncState *funcstate, SQInteger ntoresolve, SQInteger targetpos)
+ {
+ while(ntoresolve > 0) {
+ SQInteger pos = funcstate->_unresolvedcontinues.back();
+ funcstate->_unresolvedcontinues.pop_back();
+ //set the jmp instruction
+ funcstate->SetIntructionParams(pos, 0, targetpos - pos, 0);
+ ntoresolve--;
+ }
+ }
+private:
+ SQInteger _token;
+ SQFuncState *_fs;
+ SQObjectPtr _sourcename;
+ SQLexer _lex;
+ bool _lineinfo;
+ bool _raiseerror;
+ SQInteger _debugline;
+ SQInteger _debugop;
+ ExpStateVec _expstates;
+ SQChar *compilererror;
+ jmp_buf _errorjmp;
+ SQVM *_vm;
+};
+
+bool Compile(SQVM *vm,SQLEXREADFUNC rg, SQUserPointer up, const SQChar *sourcename, SQObjectPtr &out, bool raiseerror, bool lineinfo)
+{
+ SQCompiler p(vm, rg, up, sourcename, raiseerror, lineinfo);
+ return p.Compile(out);
+}
--- /dev/null
+/* see copyright notice in squirrel.h */
+#ifndef _SQCOMPILER_H_
+#define _SQCOMPILER_H_
+
+struct SQVM;
+
+#define TK_IDENTIFIER 258
+#define TK_STRING_LITERAL 259
+#define TK_INTEGER 260
+#define TK_FLOAT 261
+#define TK_DELEGATE 262
+#define TK_DELETE 263
+#define TK_EQ 264
+#define TK_NE 265
+#define TK_LE 266
+#define TK_GE 267
+#define TK_SWITCH 268
+#define TK_ARROW 269
+#define TK_AND 270
+#define TK_OR 271
+#define TK_IF 272
+#define TK_ELSE 273
+#define TK_WHILE 274
+#define TK_BREAK 275
+#define TK_FOR 276
+#define TK_DO 277
+#define TK_NULL 278
+#define TK_FOREACH 279
+#define TK_IN 280
+#define TK_NEWSLOT 281
+#define TK_MODULO 282
+#define TK_LOCAL 283
+#define TK_CLONE 284
+#define TK_FUNCTION 285
+#define TK_RETURN 286
+#define TK_TYPEOF 287
+#define TK_UMINUS 288
+#define TK_PLUSEQ 289
+#define TK_MINUSEQ 290
+#define TK_CONTINUE 291
+#define TK_YIELD 292
+#define TK_TRY 293
+#define TK_CATCH 294
+#define TK_THROW 295
+#define TK_SHIFTL 296
+#define TK_SHIFTR 297
+#define TK_RESUME 298
+#define TK_DOUBLE_COLON 299
+#define TK_CASE 300
+#define TK_DEFAULT 301
+#define TK_THIS 302
+#define TK_PLUSPLUS 303
+#define TK_MINUSMINUS 304
+#define TK_PARENT 305
+#define TK_USHIFTR 306
+#define TK_CLASS 307
+#define TK_EXTENDS 308
+#define TK_CONSTRUCTOR 310
+#define TK_INSTANCEOF 311
+#define TK_VARPARAMS 312
+#define TK_VARGC 313
+#define TK_VARGV 314
+#define TK_TRUE 315
+#define TK_FALSE 316
+#define TK_MULEQ 317
+#define TK_DIVEQ 318
+#define TK_MODEQ 319
+#define TK_ATTR_OPEN 320
+#define TK_ATTR_CLOSE 321
+#define TK_STATIC 322
+#define TK_ENUM 323
+#define TK_CONST 324
+
+
+typedef void(*CompilerErrorFunc)(void *ud, const SQChar *s);
+bool Compile(SQVM *vm, SQLEXREADFUNC rg, SQUserPointer up, const SQChar *sourcename, SQObjectPtr &out, bool raiseerror, bool lineinfo);
+#endif //_SQCOMPILER_H_
--- /dev/null
+/*
+ see copyright notice in squirrel.h
+*/
+#include "sqpcheader.h"
+#include <stdarg.h>
+#include "sqvm.h"
+#include "sqfuncproto.h"
+#include "sqclosure.h"
+#include "sqstring.h"
+
+SQRESULT sq_getfunctioninfo(HSQUIRRELVM v,SQInteger level,SQFunctionInfo *fi)
+{
+ SQInteger cssize = v->_callsstacksize;
+ if (cssize > level) {
+ SQVM::CallInfo &ci = v->_callsstack[cssize-level-1];
+ if(sq_isclosure(ci._closure)) {
+ SQClosure *c = _closure(ci._closure);
+ SQFunctionProto *proto = _funcproto(c->_function);
+ fi->funcid = proto;
+ fi->name = type(proto->_name) == OT_STRING?_stringval(proto->_name):_SC("unknown");
+ fi->source = type(proto->_name) == OT_STRING?_stringval(proto->_sourcename):_SC("unknown");
+ return SQ_OK;
+ }
+ }
+ return sq_throwerror(v,_SC("the object is not a closure"));
+}
+
+SQRESULT sq_stackinfos(HSQUIRRELVM v, SQInteger level, SQStackInfos *si)
+{
+ SQInteger cssize = v->_callsstacksize;
+ if (cssize > level) {
+ memset(si, 0, sizeof(SQStackInfos));
+ SQVM::CallInfo &ci = v->_callsstack[cssize-level-1];
+ switch (type(ci._closure)) {
+ case OT_CLOSURE:{
+ SQFunctionProto *func = _funcproto(_closure(ci._closure)->_function);
+ if (type(func->_name) == OT_STRING)
+ si->funcname = _stringval(func->_name);
+ if (type(func->_sourcename) == OT_STRING)
+ si->source = _stringval(func->_sourcename);
+ si->line = func->GetLine(ci._ip);
+ }
+ break;
+ case OT_NATIVECLOSURE:
+ si->source = _SC("NATIVE");
+ si->funcname = _SC("unknown");
+ if(type(_nativeclosure(ci._closure)->_name) == OT_STRING)
+ si->funcname = _stringval(_nativeclosure(ci._closure)->_name);
+ si->line = -1;
+ break;
+ default: break; //shutup compiler
+ }
+ return SQ_OK;
+ }
+ return SQ_ERROR;
+}
+
+void SQVM::Raise_Error(const SQChar *s, ...)
+{
+ va_list vl;
+ va_start(vl, s);
+ scvsprintf(_sp(rsl((SQInteger)scstrlen(s)+(NUMBER_MAX_CHAR*2))), s, vl);
+ va_end(vl);
+ _lasterror = SQString::Create(_ss(this),_spval,-1);
+}
+
+void SQVM::Raise_Error(SQObjectPtr &desc)
+{
+ _lasterror = desc;
+}
+
+SQString *SQVM::PrintObjVal(const SQObject &o)
+{
+ switch(type(o)) {
+ case OT_STRING: return _string(o);
+ case OT_INTEGER:
+ scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)), _SC("%d"), _integer(o));
+ return SQString::Create(_ss(this), _spval);
+ break;
+ case OT_FLOAT:
+ scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)), _SC("%.14g"), _float(o));
+ return SQString::Create(_ss(this), _spval);
+ break;
+ default:
+ return SQString::Create(_ss(this), GetTypeName(o));
+ }
+}
+
+void SQVM::Raise_IdxError(SQObject &o)
+{
+ SQObjectPtr oval = PrintObjVal(o);
+ Raise_Error(_SC("the index '%.50s' does not exist"), _stringval(oval));
+}
+
+void SQVM::Raise_CompareError(const SQObject &o1, const SQObject &o2)
+{
+ SQObjectPtr oval1 = PrintObjVal(o1), oval2 = PrintObjVal(o2);
+ Raise_Error(_SC("comparsion between '%.50s' and '%.50s'"), _stringval(oval1), _stringval(oval2));
+}
+
+
+void SQVM::Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type)
+{
+ SQObjectPtr exptypes = SQString::Create(_ss(this), _SC(""), -1);
+ SQInteger found = 0;
+ for(SQInteger i=0; i<16; i++)
+ {
+ SQInteger mask = 0x00000001 << i;
+ if(typemask & (mask)) {
+ if(found>0) StringCat(exptypes,SQString::Create(_ss(this), _SC("|"), -1), exptypes);
+ found ++;
+ StringCat(exptypes,SQString::Create(_ss(this), IdType2Name((SQObjectType)mask), -1), exptypes);
+ }
+ }
+ Raise_Error(_SC("parameter %d has an invalid type '%s' ; expected: '%s'"), nparam, IdType2Name((SQObjectType)type), _stringval(exptypes));
+}
--- /dev/null
+/* see copyright notice in squirrel.h */
+#ifndef _SQFUNCTION_H_
+#define _SQFUNCTION_H_
+
+#include "sqopcodes.h"
+
+enum SQOuterType {
+ otLOCAL = 0,
+ otSYMBOL = 1,
+ otOUTER = 2
+};
+
+struct SQOuterVar
+{
+
+ SQOuterVar(){}
+ SQOuterVar(const SQObjectPtr &name,const SQObjectPtr &src,SQOuterType t)
+ {
+ _name = name;
+ _src=src;
+ _type=t;
+ }
+ SQOuterVar(const SQOuterVar &ov)
+ {
+ _type=ov._type;
+ _src=ov._src;
+ _name=ov._name;
+ }
+ SQOuterType _type;
+ SQObjectPtr _name;
+ SQObjectPtr _src;
+};
+
+struct SQLocalVarInfo
+{
+ SQLocalVarInfo():_start_op(0),_end_op(0){}
+ SQLocalVarInfo(const SQLocalVarInfo &lvi)
+ {
+ _name=lvi._name;
+ _start_op=lvi._start_op;
+ _end_op=lvi._end_op;
+ _pos=lvi._pos;
+ }
+ SQObjectPtr _name;
+ SQUnsignedInteger _start_op;
+ SQUnsignedInteger _end_op;
+ SQUnsignedInteger _pos;
+};
+
+struct SQLineInfo { SQInteger _line;SQInteger _op; };
+
+typedef sqvector<SQOuterVar> SQOuterVarVec;
+typedef sqvector<SQLocalVarInfo> SQLocalVarInfoVec;
+typedef sqvector<SQLineInfo> SQLineInfoVec;
+
+#define _FUNC_SIZE(ni,nl,nparams,nfuncs,nouters,nlineinf,localinf,defparams) (sizeof(SQFunctionProto) \
+ +((ni-1)*sizeof(SQInstruction))+(nl*sizeof(SQObjectPtr)) \
+ +(nparams*sizeof(SQObjectPtr))+(nfuncs*sizeof(SQObjectPtr)) \
+ +(nouters*sizeof(SQOuterVar))+(nlineinf*sizeof(SQLineInfo)) \
+ +(localinf*sizeof(SQLocalVarInfo))+(defparams*sizeof(SQInteger)))
+
+#define _CONSTRUCT_VECTOR(type,size,ptr) { \
+ for(SQInteger n = 0; n < size; n++) { \
+ new (&ptr[n]) type(); \
+ } \
+}
+
+#define _DESTRUCT_VECTOR(type,size,ptr) { \
+ for(SQInteger nl = 0; nl < size; nl++) { \
+ ptr[nl].~type(); \
+ } \
+}
+struct SQFunctionProto : public SQRefCounted
+{
+private:
+ SQFunctionProto(){
+ _stacksize=0;
+ _bgenerator=false;}
+public:
+ static SQFunctionProto *Create(SQInteger ninstructions,
+ SQInteger nliterals,SQInteger nparameters,
+ SQInteger nfunctions,SQInteger noutervalues,
+ SQInteger nlineinfos,SQInteger nlocalvarinfos,SQInteger ndefaultparams)
+ {
+ SQFunctionProto *f;
+ //I compact the whole class and members in a single memory allocation
+ f = (SQFunctionProto *)sq_vm_malloc(_FUNC_SIZE(ninstructions,nliterals,nparameters,nfunctions,noutervalues,nlineinfos,nlocalvarinfos,ndefaultparams));
+ new (f) SQFunctionProto;
+ f->_ninstructions = ninstructions;
+ f->_literals = (SQObjectPtr*)&f->_instructions[ninstructions];
+ f->_nliterals = nliterals;
+ f->_parameters = (SQObjectPtr*)&f->_literals[nliterals];
+ f->_nparameters = nparameters;
+ f->_functions = (SQObjectPtr*)&f->_parameters[nparameters];
+ f->_nfunctions = nfunctions;
+ f->_outervalues = (SQOuterVar*)&f->_functions[nfunctions];
+ f->_noutervalues = noutervalues;
+ f->_lineinfos = (SQLineInfo *)&f->_outervalues[noutervalues];
+ f->_nlineinfos = nlineinfos;
+ f->_localvarinfos = (SQLocalVarInfo *)&f->_lineinfos[nlineinfos];
+ f->_nlocalvarinfos = nlocalvarinfos;
+ f->_defaultparams = (SQInteger *)&f->_localvarinfos[nlocalvarinfos];
+ f->_ndefaultparams = ndefaultparams;
+
+ _CONSTRUCT_VECTOR(SQObjectPtr,f->_nliterals,f->_literals);
+ _CONSTRUCT_VECTOR(SQObjectPtr,f->_nparameters,f->_parameters);
+ _CONSTRUCT_VECTOR(SQObjectPtr,f->_nfunctions,f->_functions);
+ _CONSTRUCT_VECTOR(SQOuterVar,f->_noutervalues,f->_outervalues);
+ //_CONSTRUCT_VECTOR(SQLineInfo,f->_nlineinfos,f->_lineinfos); //not required are 2 integers
+ _CONSTRUCT_VECTOR(SQLocalVarInfo,f->_nlocalvarinfos,f->_localvarinfos);
+ return f;
+ }
+ void Release(){
+ _DESTRUCT_VECTOR(SQObjectPtr,_nliterals,_literals);
+ _DESTRUCT_VECTOR(SQObjectPtr,_nparameters,_parameters);
+ _DESTRUCT_VECTOR(SQObjectPtr,_nfunctions,_functions);
+ _DESTRUCT_VECTOR(SQOuterVar,_noutervalues,_outervalues);
+ //_DESTRUCT_VECTOR(SQLineInfo,_nlineinfos,_lineinfos); //not required are 2 integers
+ _DESTRUCT_VECTOR(SQLocalVarInfo,_nlocalvarinfos,_localvarinfos);
+ SQInteger size = _FUNC_SIZE(_ninstructions,_nliterals,_nparameters,_nfunctions,_noutervalues,_nlineinfos,_nlocalvarinfos,_ndefaultparams);
+ this->~SQFunctionProto();
+ sq_vm_free(this,size);
+ }
+ const SQChar* GetLocal(SQVM *v,SQUnsignedInteger stackbase,SQUnsignedInteger nseq,SQUnsignedInteger nop);
+ SQInteger GetLine(SQInstruction *curr);
+ bool Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write);
+ static bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret);
+
+ SQObjectPtr _sourcename;
+ SQObjectPtr _name;
+ SQInteger _stacksize;
+ bool _bgenerator;
+ bool _varparams;
+
+ SQInteger _nlocalvarinfos;
+ SQLocalVarInfo *_localvarinfos;
+
+ SQInteger _nlineinfos;
+ SQLineInfo *_lineinfos;
+
+ SQInteger _nliterals;
+ SQObjectPtr *_literals;
+
+ SQInteger _nparameters;
+ SQObjectPtr *_parameters;
+
+ SQInteger _nfunctions;
+ SQObjectPtr *_functions;
+
+ SQInteger _noutervalues;
+ SQOuterVar *_outervalues;
+
+ SQInteger _ndefaultparams;
+ SQInteger *_defaultparams;
+
+ SQInteger _ninstructions;
+ SQInstruction _instructions[1];
+};
+
+#endif //_SQFUNCTION_H_
--- /dev/null
+/*
+ see copyright notice in squirrel.h
+*/
+#include "sqpcheader.h"
+#include "sqcompiler.h"
+#include "sqfuncproto.h"
+#include "sqstring.h"
+#include "sqtable.h"
+#include "sqopcodes.h"
+#include "sqfuncstate.h"
+
+#ifdef _DEBUG_DUMP
+SQInstructionDesc g_InstrDesc[]={
+ {_SC("_OP_LINE")},
+ {_SC("_OP_LOAD")},
+ {_SC("_OP_LOADINT")},
+ {_SC("_OP_LOADFLOAT")},
+ {_SC("_OP_DLOAD")},
+ {_SC("_OP_TAILCALL")},
+ {_SC("_OP_CALL")},
+ {_SC("_OP_PREPCALL")},
+ {_SC("_OP_PREPCALLK")},
+ {_SC("_OP_GETK")},
+ {_SC("_OP_MOVE")},
+ {_SC("_OP_NEWSLOT")},
+ {_SC("_OP_DELETE")},
+ {_SC("_OP_SET")},
+ {_SC("_OP_GET")},
+ {_SC("_OP_EQ")},
+ {_SC("_OP_NE")},
+ {_SC("_OP_ARITH")},
+ {_SC("_OP_BITW")},
+ {_SC("_OP_RETURN")},
+ {_SC("_OP_LOADNULLS")},
+ {_SC("_OP_LOADROOTTABLE")},
+ {_SC("_OP_LOADBOOL")},
+ {_SC("_OP_DMOVE")},
+ {_SC("_OP_JMP")},
+ {_SC("_OP_JNZ")},
+ {_SC("_OP_JZ")},
+ {_SC("_OP_LOADFREEVAR")},
+ {_SC("_OP_VARGC")},
+ {_SC("_OP_GETVARGV")},
+ {_SC("_OP_NEWTABLE")},
+ {_SC("_OP_NEWARRAY")},
+ {_SC("_OP_APPENDARRAY")},
+ {_SC("_OP_GETPARENT")},
+ {_SC("_OP_COMPARITH")},
+ {_SC("_OP_COMPARITHL")},
+ {_SC("_OP_INC")},
+ {_SC("_OP_INCL")},
+ {_SC("_OP_PINC")},
+ {_SC("_OP_PINCL")},
+ {_SC("_OP_CMP")},
+ {_SC("_OP_EXISTS")},
+ {_SC("_OP_INSTANCEOF")},
+ {_SC("_OP_AND")},
+ {_SC("_OP_OR")},
+ {_SC("_OP_NEG")},
+ {_SC("_OP_NOT")},
+ {_SC("_OP_BWNOT")},
+ {_SC("_OP_CLOSURE")},
+ {_SC("_OP_YIELD")},
+ {_SC("_OP_RESUME")},
+ {_SC("_OP_FOREACH")},
+ {_SC("_OP_POSTFOREACH")},
+ {_SC("_OP_DELEGATE")},
+ {_SC("_OP_CLONE")},
+ {_SC("_OP_TYPEOF")},
+ {_SC("_OP_PUSHTRAP")},
+ {_SC("_OP_POPTRAP")},
+ {_SC("_OP_THROW")},
+ {_SC("_OP_CLASS")},
+ {_SC("_OP_NEWSLOTA")}
+};
+#endif
+void DumpLiteral(SQObjectPtr &o)
+{
+ switch(type(o)){
+ case OT_STRING: scprintf(_SC("\"%s\""),_stringval(o));break;
+ case OT_FLOAT: scprintf(_SC("{%f}"),_float(o));break;
+ case OT_INTEGER: scprintf(_SC("{%d}"),_integer(o));break;
+ case OT_BOOL: scprintf(_SC("%s"),_integer(o)?_SC("true"):_SC("false"));break;
+ default: scprintf(_SC("(%s %p)"),GetTypeName(o),_rawval(o));break; break; //shut up compiler
+ }
+}
+
+SQFuncState::SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc efunc,void *ed)
+{
+ _nliterals = 0;
+ _literals = SQTable::Create(ss,0);
+ _strings = SQTable::Create(ss,0);
+ _sharedstate = ss;
+ _lastline = 0;
+ _optimization = true;
+ _parent = parent;
+ _stacksize = 0;
+ _traps = 0;
+ _returnexp = 0;
+ _varparams = false;
+ _errfunc = efunc;
+ _errtarget = ed;
+ _bgenerator = false;
+
+}
+
+void SQFuncState::Error(const SQChar *err)
+{
+ _errfunc(_errtarget,err);
+}
+
+#ifdef _DEBUG_DUMP
+void SQFuncState::Dump(SQFunctionProto *func)
+{
+ SQUnsignedInteger n=0,i;
+ SQInteger si;
+ scprintf(_SC("SQInstruction sizeof %d\n"),sizeof(SQInstruction));
+ scprintf(_SC("SQObject sizeof %d\n"),sizeof(SQObject));
+ scprintf(_SC("--------------------------------------------------------------------\n"));
+ scprintf(_SC("*****FUNCTION [%s]\n"),type(func->_name)==OT_STRING?_stringval(func->_name):_SC("unknown"));
+ scprintf(_SC("-----LITERALS\n"));
+ SQObjectPtr refidx,key,val;
+ SQInteger idx;
+ SQObjectPtrVec templiterals;
+ templiterals.resize(_nliterals);
+ while((idx=_table(_literals)->Next(false,refidx,key,val))!=-1) {
+ refidx=idx;
+ templiterals[_integer(val)]=key;
+ }
+ for(i=0;i<templiterals.size();i++){
+ scprintf(_SC("[%d] "),n);
+ DumpLiteral(templiterals[i]);
+ scprintf(_SC("\n"));
+ n++;
+ }
+ scprintf(_SC("-----PARAMS\n"));
+ if(_varparams)
+ scprintf(_SC("<<VARPARAMS>>\n"));
+ n=0;
+ for(i=0;i<_parameters.size();i++){
+ scprintf(_SC("[%d] "),n);
+ DumpLiteral(_parameters[i]);
+ scprintf(_SC("\n"));
+ n++;
+ }
+ scprintf(_SC("-----LOCALS\n"));
+ for(si=0;si<func->_nlocalvarinfos;si++){
+ SQLocalVarInfo lvi=func->_localvarinfos[si];
+ scprintf(_SC("[%d] %s \t%d %d\n"),lvi._pos,_stringval(lvi._name),lvi._start_op,lvi._end_op);
+ n++;
+ }
+ scprintf(_SC("-----LINE INFO\n"));
+ for(i=0;i<_lineinfos.size();i++){
+ SQLineInfo li=_lineinfos[i];
+ scprintf(_SC("op [%d] line [%d] \n"),li._op,li._line);
+ n++;
+ }
+ scprintf(_SC("-----dump\n"));
+ n=0;
+ for(i=0;i<_instructions.size();i++){
+ SQInstruction &inst=_instructions[i];
+ if(inst.op==_OP_LOAD || inst.op==_OP_DLOAD || inst.op==_OP_PREPCALLK || inst.op==_OP_GETK ){
+
+ SQInteger lidx = inst._arg1;
+ scprintf(_SC("[%03d] %15s %d "),n,g_InstrDesc[inst.op].name,inst._arg0);
+ if(lidx >= 0xFFFFFFFF)
+ scprintf(_SC("null"));
+ else {
+ SQInteger refidx;
+ SQObjectPtr val,key,refo;
+ while(((refidx=_table(_literals)->Next(false,refo,key,val))!= -1) && (_integer(val) != lidx)) {
+ refo = refidx;
+ }
+ DumpLiteral(key);
+ }
+ if(inst.op != _OP_DLOAD) {
+ scprintf(_SC(" %d %d \n"),inst._arg2,inst._arg3);
+ }
+ else {
+ scprintf(_SC(" %d "),inst._arg2);
+ lidx = inst._arg3;
+ if(lidx >= 0xFFFFFFFF)
+ scprintf(_SC("null"));
+ else {
+ SQInteger refidx;
+ SQObjectPtr val,key,refo;
+ while(((refidx=_table(_literals)->Next(false,refo,key,val))!= -1) && (_integer(val) != lidx)) {
+ refo = refidx;
+ }
+ DumpLiteral(key);
+ scprintf(_SC("\n"));
+ }
+ }
+ }
+ else if(inst.op==_OP_LOADFLOAT) {
+ scprintf(_SC("[%03d] %15s %d %f %d %d\n"),n,g_InstrDesc[inst.op].name,inst._arg0,*((SQFloat*)&inst._arg1),inst._arg2,inst._arg3);
+ }
+ else if(inst.op==_OP_ARITH){
+ scprintf(_SC("[%03d] %15s %d %d %d %c\n"),n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3);
+ }
+ else
+ scprintf(_SC("[%03d] %15s %d %d %d %d\n"),n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3);
+ n++;
+ }
+ scprintf(_SC("-----\n"));
+ scprintf(_SC("stack size[%d]\n"),func->_stacksize);
+ scprintf(_SC("--------------------------------------------------------------------\n\n"));
+}
+#endif
+
+SQInteger SQFuncState::GetNumericConstant(const SQInteger cons)
+{
+ return GetConstant(SQObjectPtr(cons));
+}
+
+SQInteger SQFuncState::GetNumericConstant(const SQFloat cons)
+{
+ return GetConstant(SQObjectPtr(cons));
+}
+
+SQInteger SQFuncState::GetConstant(const SQObject &cons)
+{
+ SQObjectPtr val;
+ if(!_table(_literals)->Get(cons,val))
+ {
+ val = _nliterals;
+ _table(_literals)->NewSlot(cons,val);
+ _nliterals++;
+ if(_nliterals > MAX_LITERALS) {
+ val.Null();
+ Error(_SC("internal compiler error: too many literals"));
+ }
+ }
+ return _integer(val);
+}
+
+void SQFuncState::SetIntructionParams(SQInteger pos,SQInteger arg0,SQInteger arg1,SQInteger arg2,SQInteger arg3)
+{
+ _instructions[pos]._arg0=(unsigned char)*((SQUnsignedInteger *)&arg0);
+ _instructions[pos]._arg1=(SQInt32)*((SQUnsignedInteger *)&arg1);
+ _instructions[pos]._arg2=(unsigned char)*((SQUnsignedInteger *)&arg2);
+ _instructions[pos]._arg3=(unsigned char)*((SQUnsignedInteger *)&arg3);
+}
+
+void SQFuncState::SetIntructionParam(SQInteger pos,SQInteger arg,SQInteger val)
+{
+ switch(arg){
+ case 0:_instructions[pos]._arg0=(unsigned char)*((SQUnsignedInteger *)&val);break;
+ case 1:case 4:_instructions[pos]._arg1=(SQInt32)*((SQUnsignedInteger *)&val);break;
+ case 2:_instructions[pos]._arg2=(unsigned char)*((SQUnsignedInteger *)&val);break;
+ case 3:_instructions[pos]._arg3=(unsigned char)*((SQUnsignedInteger *)&val);break;
+ };
+}
+
+SQInteger SQFuncState::AllocStackPos()
+{
+ SQInteger npos=_vlocals.size();
+ _vlocals.push_back(SQLocalVarInfo());
+ if(_vlocals.size()>((SQUnsignedInteger)_stacksize)) {
+ if(_stacksize>MAX_FUNC_STACKSIZE) Error(_SC("internal compiler error: too many locals"));
+ _stacksize=_vlocals.size();
+ }
+ return npos;
+}
+
+SQInteger SQFuncState::PushTarget(SQInteger n)
+{
+ if(n!=-1){
+ _targetstack.push_back(n);
+ return n;
+ }
+ n=AllocStackPos();
+ _targetstack.push_back(n);
+ return n;
+}
+
+SQInteger SQFuncState::GetUpTarget(SQInteger n){
+ return _targetstack[((_targetstack.size()-1)-n)];
+}
+
+SQInteger SQFuncState::TopTarget(){
+ return _targetstack.back();
+}
+SQInteger SQFuncState::PopTarget()
+{
+ SQInteger npos=_targetstack.back();
+ SQLocalVarInfo t=_vlocals[_targetstack.back()];
+ if(type(t._name)==OT_NULL){
+ _vlocals.pop_back();
+ }
+ _targetstack.pop_back();
+ return npos;
+}
+
+SQInteger SQFuncState::GetStackSize()
+{
+ return _vlocals.size();
+}
+
+void SQFuncState::SetStackSize(SQInteger n)
+{
+ SQInteger size=_vlocals.size();
+ while(size>n){
+ size--;
+ SQLocalVarInfo lvi=_vlocals.back();
+ if(type(lvi._name)!=OT_NULL){
+ lvi._end_op=GetCurrentPos();
+ _localvarinfos.push_back(lvi);
+ }
+ _vlocals.pop_back();
+ }
+}
+
+bool SQFuncState::IsConstant(const SQObject &name,SQObject &e)
+{
+ SQObjectPtr val;
+ if(_table(_sharedstate->_consts)->Get(name,val)) {
+ e = val;
+ return true;
+ }
+ return false;
+}
+
+bool SQFuncState::IsLocal(SQUnsignedInteger stkpos)
+{
+ if(stkpos>=_vlocals.size())return false;
+ else if(type(_vlocals[stkpos]._name)!=OT_NULL)return true;
+ return false;
+}
+
+SQInteger SQFuncState::PushLocalVariable(const SQObject &name)
+{
+ SQInteger pos=_vlocals.size();
+ SQLocalVarInfo lvi;
+ lvi._name=name;
+ lvi._start_op=GetCurrentPos()+1;
+ lvi._pos=_vlocals.size();
+ _vlocals.push_back(lvi);
+ if(_vlocals.size()>((SQUnsignedInteger)_stacksize))_stacksize=_vlocals.size();
+
+ return pos;
+}
+
+SQInteger SQFuncState::GetLocalVariable(const SQObject &name)
+{
+ SQInteger locals=_vlocals.size();
+ while(locals>=1){
+ if(type(_vlocals[locals-1]._name)==OT_STRING && _string(_vlocals[locals-1]._name)==_string(name)){
+ return locals-1;
+ }
+ locals--;
+ }
+ return -1;
+}
+
+SQInteger SQFuncState::GetOuterVariable(const SQObject &name)
+{
+ SQInteger outers = _outervalues.size();
+ for(SQInteger i = 0; i<outers; i++) {
+ if(_string(_outervalues[i]._name) == _string(name))
+ return i;
+ }
+ return -1;
+}
+
+void SQFuncState::AddOuterValue(const SQObject &name)
+{
+ SQInteger pos=-1;
+ if(_parent) {
+ pos = _parent->GetLocalVariable(name);
+ if(pos == -1) {
+ pos = _parent->GetOuterVariable(name);
+ if(pos != -1) {
+ _outervalues.push_back(SQOuterVar(name,SQObjectPtr(SQInteger(pos)),otOUTER)); //local
+ return;
+ }
+ }
+ else {
+ _outervalues.push_back(SQOuterVar(name,SQObjectPtr(SQInteger(pos)),otLOCAL)); //local
+ return;
+ }
+ }
+ _outervalues.push_back(SQOuterVar(name,name,otSYMBOL)); //global
+}
+
+void SQFuncState::AddParameter(const SQObject &name)
+{
+ PushLocalVariable(name);
+ _parameters.push_back(name);
+}
+
+void SQFuncState::AddLineInfos(SQInteger line,bool lineop,bool force)
+{
+ if(_lastline!=line || force){
+ SQLineInfo li;
+ li._line=line;li._op=(GetCurrentPos()+1);
+ if(lineop)AddInstruction(_OP_LINE,0,line);
+ _lineinfos.push_back(li);
+ _lastline=line;
+ }
+}
+
+void SQFuncState::AddInstruction(SQInstruction &i)
+{
+ SQInteger size = _instructions.size();
+ if(size > 0 && _optimization){ //simple optimizer
+ SQInstruction &pi = _instructions[size-1];//previous instruction
+ switch(i.op) {
+ case _OP_RETURN:
+ if( _parent && i._arg0 != MAX_FUNC_STACKSIZE && pi.op == _OP_CALL && _returnexp < size-1) {
+ pi.op = _OP_TAILCALL;
+ }
+ break;
+ case _OP_GET:
+ if( pi.op == _OP_LOAD && pi._arg0 == i._arg2 && (!IsLocal(pi._arg0))){
+ pi._arg1 = pi._arg1;
+ pi._arg2 = (unsigned char)i._arg1;
+ pi.op = _OP_GETK;
+ pi._arg0 = i._arg0;
+
+ return;
+ }
+ break;
+ case _OP_PREPCALL:
+ if( pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0))){
+ pi.op = _OP_PREPCALLK;
+ pi._arg0 = i._arg0;
+ pi._arg1 = pi._arg1;
+ pi._arg2 = i._arg2;
+ pi._arg3 = i._arg3;
+ return;
+ }
+ break;
+ case _OP_APPENDARRAY:
+ if(pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0))){
+ pi.op = _OP_APPENDARRAY;
+ pi._arg0 = i._arg0;
+ pi._arg1 = pi._arg1;
+ pi._arg2 = MAX_FUNC_STACKSIZE;
+ pi._arg3 = MAX_FUNC_STACKSIZE;
+ return;
+ }
+ break;
+ case _OP_MOVE:
+ if((pi.op == _OP_GET || pi.op == _OP_ARITH || pi.op == _OP_BITW) && (pi._arg0 == i._arg1))
+ {
+ pi._arg0 = i._arg0;
+ _optimization = false;
+ return;
+ }
+
+ if(pi.op == _OP_MOVE)
+ {
+ pi.op = _OP_DMOVE;
+ pi._arg2 = i._arg0;
+ pi._arg3 = (unsigned char)i._arg1;
+ return;
+ }
+ break;
+ case _OP_LOAD:
+ if(pi.op == _OP_LOAD && i._arg1 < 256) {
+ pi.op = _OP_DLOAD;
+ pi._arg2 = i._arg0;
+ pi._arg3 = (unsigned char)i._arg1;
+ return;
+ }
+ break;
+ case _OP_EQ:case _OP_NE:
+ if(pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0) ))
+ {
+ pi.op = i.op;
+ pi._arg0 = i._arg0;
+ pi._arg1 = pi._arg1;
+ pi._arg2 = i._arg2;
+ pi._arg3 = MAX_FUNC_STACKSIZE;
+ return;
+ }
+ break;
+ case _OP_LOADNULLS:
+ if((pi.op == _OP_LOADNULLS && pi._arg0+pi._arg1 == i._arg0)) {
+
+ pi._arg1 = pi._arg1 + 1;
+ pi.op = _OP_LOADNULLS;
+ return;
+ }
+ break;
+ case _OP_LINE:
+ if(pi.op == _OP_LINE) {
+ _instructions.pop_back();
+ _lineinfos.pop_back();
+ }
+ break;
+ }
+ }
+ _optimization = true;
+ _instructions.push_back(i);
+}
+
+SQObject SQFuncState::CreateString(const SQChar *s,SQInteger len)
+{
+ SQObjectPtr ns(SQString::Create(_sharedstate,s,len));
+ _table(_strings)->NewSlot(ns,(SQInteger)1);
+ return ns;
+}
+
+SQObject SQFuncState::CreateTable()
+{
+ SQObjectPtr nt(SQTable::Create(_sharedstate,0));
+ _table(_strings)->NewSlot(nt,(SQInteger)1);
+ return nt;
+}
+
+SQFunctionProto *SQFuncState::BuildProto()
+{
+ SQFunctionProto *f=SQFunctionProto::Create(_instructions.size(),
+ _nliterals,_parameters.size(),_functions.size(),_outervalues.size(),
+ _lineinfos.size(),_localvarinfos.size(),_defaultparams.size());
+
+ SQObjectPtr refidx,key,val;
+ SQInteger idx;
+
+ f->_stacksize = _stacksize;
+ f->_sourcename = _sourcename;
+ f->_bgenerator = _bgenerator;
+ f->_name = _name;
+
+ while((idx=_table(_literals)->Next(false,refidx,key,val))!=-1) {
+ f->_literals[_integer(val)]=key;
+ refidx=idx;
+ }
+
+ for(SQUnsignedInteger nf = 0; nf < _functions.size(); nf++) f->_functions[nf] = _functions[nf];
+ for(SQUnsignedInteger np = 0; np < _parameters.size(); np++) f->_parameters[np] = _parameters[np];
+ for(SQUnsignedInteger no = 0; no < _outervalues.size(); no++) f->_outervalues[no] = _outervalues[no];
+ for(SQUnsignedInteger no = 0; no < _localvarinfos.size(); no++) f->_localvarinfos[no] = _localvarinfos[no];
+ for(SQUnsignedInteger no = 0; no < _lineinfos.size(); no++) f->_lineinfos[no] = _lineinfos[no];
+ for(SQUnsignedInteger no = 0; no < _defaultparams.size(); no++) f->_defaultparams[no] = _defaultparams[no];
+
+ memcpy(f->_instructions,&_instructions[0],_instructions.size()*sizeof(SQInstruction));
+
+ f->_varparams = _varparams;
+
+ return f;
+}
+
+SQFuncState *SQFuncState::PushChildState(SQSharedState *ss)
+{
+ SQFuncState *child = (SQFuncState *)sq_malloc(sizeof(SQFuncState));
+ new (child) SQFuncState(ss,this,_errfunc,_errtarget);
+ _childstates.push_back(child);
+ return child;
+}
+
+void SQFuncState::PopChildState()
+{
+ SQFuncState *child = _childstates.back();
+ sq_delete(child,SQFuncState);
+ _childstates.pop_back();
+}
+
+SQFuncState::~SQFuncState()
+{
+ while(_childstates.size() > 0)
+ {
+ PopChildState();
+ }
+}
--- /dev/null
+/* see copyright notice in squirrel.h */
+#ifndef _SQFUNCSTATE_H_
+#define _SQFUNCSTATE_H_
+///////////////////////////////////
+#include "squtils.h"
+
+struct SQFuncState
+{
+ SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc efunc,void *ed);
+ ~SQFuncState();
+#ifdef _DEBUG_DUMP
+ void Dump(SQFunctionProto *func);
+#endif
+ void Error(const SQChar *err);
+ SQFuncState *PushChildState(SQSharedState *ss);
+ void PopChildState();
+ void AddInstruction(SQOpcode _op,SQInteger arg0=0,SQInteger arg1=0,SQInteger arg2=0,SQInteger arg3=0){SQInstruction i(_op,arg0,arg1,arg2,arg3);AddInstruction(i);}
+ void AddInstruction(SQInstruction &i);
+ void SetIntructionParams(SQInteger pos,SQInteger arg0,SQInteger arg1,SQInteger arg2=0,SQInteger arg3=0);
+ void SetIntructionParam(SQInteger pos,SQInteger arg,SQInteger val);
+ SQInstruction &GetInstruction(SQInteger pos){return _instructions[pos];}
+ void PopInstructions(SQInteger size){for(SQInteger i=0;i<size;i++)_instructions.pop_back();}
+ void SetStackSize(SQInteger n);
+ void SnoozeOpt(){_optimization=false;}
+ void AddDefaultParam(SQInteger trg) { _defaultparams.push_back(trg); }
+ SQInteger GetDefaultParamCount() { return _defaultparams.size(); }
+ SQInteger GetCurrentPos(){return _instructions.size()-1;}
+ SQInteger GetNumericConstant(const SQInteger cons);
+ SQInteger GetNumericConstant(const SQFloat cons);
+ SQInteger PushLocalVariable(const SQObject &name);
+ void AddParameter(const SQObject &name);
+ void AddOuterValue(const SQObject &name);
+ SQInteger GetLocalVariable(const SQObject &name);
+ SQInteger GetOuterVariable(const SQObject &name);
+ SQInteger GenerateCode();
+ SQInteger GetStackSize();
+ SQInteger CalcStackFrameSize();
+ void AddLineInfos(SQInteger line,bool lineop,bool force=false);
+ SQFunctionProto *BuildProto();
+ SQInteger AllocStackPos();
+ SQInteger PushTarget(SQInteger n=-1);
+ SQInteger PopTarget();
+ SQInteger TopTarget();
+ SQInteger GetUpTarget(SQInteger n);
+ bool IsLocal(SQUnsignedInteger stkpos);
+ SQObject CreateString(const SQChar *s,SQInteger len = -1);
+ SQObject CreateTable();
+ bool IsConstant(const SQObject &name,SQObject &e);
+ SQInteger _returnexp;
+ SQLocalVarInfoVec _vlocals;
+ SQIntVec _targetstack;
+ SQInteger _stacksize;
+ bool _varparams;
+ bool _bgenerator;
+ SQIntVec _unresolvedbreaks;
+ SQIntVec _unresolvedcontinues;
+ SQObjectPtrVec _functions;
+ SQObjectPtrVec _parameters;
+ SQOuterVarVec _outervalues;
+ SQInstructionVec _instructions;
+ SQLocalVarInfoVec _localvarinfos;
+ SQObjectPtr _literals;
+ SQObjectPtr _strings;
+ SQObjectPtr _name;
+ SQObjectPtr _sourcename;
+ SQInteger _nliterals;
+ SQLineInfoVec _lineinfos;
+ SQFuncState *_parent;
+ SQIntVec _breaktargets;
+ SQIntVec _continuetargets;
+ SQIntVec _defaultparams;
+ SQInteger _lastline;
+ SQInteger _traps; //contains number of nested exception traps
+ bool _optimization;
+ SQSharedState *_sharedstate;
+ sqvector<SQFuncState*> _childstates;
+ SQInteger GetConstant(const SQObject &cons);
+private:
+ CompilerErrorFunc _errfunc;
+ void *_errtarget;
+};
+
+
+#endif //_SQFUNCSTATE_H_
+
--- /dev/null
+/*
+ see copyright notice in squirrel.h
+*/
+#include "sqpcheader.h"
+#include <ctype.h>
+#include <stdlib.h>
+#include "sqtable.h"
+#include "sqstring.h"
+#include "sqcompiler.h"
+#include "sqlexer.h"
+
+#define CUR_CHAR (_currdata)
+#define RETURN_TOKEN(t) { _prevtoken = _curtoken; _curtoken = t; return t;}
+#define IS_EOB() (CUR_CHAR <= SQUIRREL_EOB)
+#define NEXT() {Next();_currentcolumn++;}
+#define INIT_TEMP_STRING() { _longstr.resize(0);}
+#define APPEND_CHAR(c) { _longstr.push_back(c);}
+#define TERMINATE_BUFFER() {_longstr.push_back(_SC('\0'));}
+#define ADD_KEYWORD(key,id) _keywords->NewSlot( SQString::Create(ss, _SC(#key)) ,SQInteger(id))
+
+SQLexer::SQLexer(){}
+SQLexer::~SQLexer()
+{
+ _keywords->Release();
+}
+
+void SQLexer::Init(SQSharedState *ss, SQLEXREADFUNC rg, SQUserPointer up,CompilerErrorFunc efunc,void *ed)
+{
+ _errfunc = efunc;
+ _errtarget = ed;
+ _sharedstate = ss;
+ _keywords = SQTable::Create(ss, 26);
+ ADD_KEYWORD(while, TK_WHILE);
+ ADD_KEYWORD(do, TK_DO);
+ ADD_KEYWORD(if, TK_IF);
+ ADD_KEYWORD(else, TK_ELSE);
+ ADD_KEYWORD(break, TK_BREAK);
+ ADD_KEYWORD(continue, TK_CONTINUE);
+ ADD_KEYWORD(return, TK_RETURN);
+ ADD_KEYWORD(null, TK_NULL);
+ ADD_KEYWORD(function, TK_FUNCTION);
+ ADD_KEYWORD(local, TK_LOCAL);
+ ADD_KEYWORD(for, TK_FOR);
+ ADD_KEYWORD(foreach, TK_FOREACH);
+ ADD_KEYWORD(in, TK_IN);
+ ADD_KEYWORD(typeof, TK_TYPEOF);
+ ADD_KEYWORD(delegate, TK_DELEGATE);
+ ADD_KEYWORD(delete, TK_DELETE);
+ ADD_KEYWORD(try, TK_TRY);
+ ADD_KEYWORD(catch, TK_CATCH);
+ ADD_KEYWORD(throw, TK_THROW);
+ ADD_KEYWORD(clone, TK_CLONE);
+ ADD_KEYWORD(yield, TK_YIELD);
+ ADD_KEYWORD(resume, TK_RESUME);
+ ADD_KEYWORD(switch, TK_SWITCH);
+ ADD_KEYWORD(case, TK_CASE);
+ ADD_KEYWORD(default, TK_DEFAULT);
+ ADD_KEYWORD(this, TK_THIS);
+ ADD_KEYWORD(parent,TK_PARENT);
+ ADD_KEYWORD(class,TK_CLASS);
+ ADD_KEYWORD(extends,TK_EXTENDS);
+ ADD_KEYWORD(constructor,TK_CONSTRUCTOR);
+ ADD_KEYWORD(instanceof,TK_INSTANCEOF);
+ ADD_KEYWORD(vargc,TK_VARGC);
+ ADD_KEYWORD(vargv,TK_VARGV);
+ ADD_KEYWORD(true,TK_TRUE);
+ ADD_KEYWORD(false,TK_FALSE);
+ ADD_KEYWORD(static,TK_STATIC);
+ ADD_KEYWORD(enum,TK_ENUM);
+ ADD_KEYWORD(const,TK_CONST);
+
+ _readf = rg;
+ _up = up;
+ _lasttokenline = _currentline = 1;
+ _currentcolumn = 0;
+ _prevtoken = -1;
+ Next();
+}
+
+void SQLexer::Error(const SQChar *err)
+{
+ _errfunc(_errtarget,err);
+}
+
+void SQLexer::Next()
+{
+ SQInteger t = _readf(_up);
+ if(t > MAX_CHAR) Error(_SC("Invalid character"));
+ if(t != 0) {
+ _currdata = (LexChar)t;
+ return;
+ }
+ _currdata = SQUIRREL_EOB;
+}
+
+const SQChar *SQLexer::Tok2Str(SQInteger tok)
+{
+ SQObjectPtr itr, key, val;
+ SQInteger nitr;
+ while((nitr = _keywords->Next(false,itr, key, val)) != -1) {
+ itr = (SQInteger)nitr;
+ if(((SQInteger)_integer(val)) == tok)
+ return _stringval(key);
+ }
+ return NULL;
+}
+
+void SQLexer::LexBlockComment()
+{
+ bool done = false;
+ while(!done) {
+ switch(CUR_CHAR) {
+ case _SC('*'): { NEXT(); if(CUR_CHAR == _SC('/')) { done = true; NEXT(); }}; continue;
+ case _SC('\n'): _currentline++; NEXT(); continue;
+ case SQUIRREL_EOB: Error(_SC("missing \"*/\" in comment"));
+ default: NEXT();
+ }
+ }
+}
+
+SQInteger SQLexer::Lex()
+{
+ _lasttokenline = _currentline;
+ while(CUR_CHAR != SQUIRREL_EOB) {
+ switch(CUR_CHAR){
+ case _SC('\t'): case _SC('\r'): case _SC(' '): NEXT(); continue;
+ case _SC('\n'):
+ _currentline++;
+ _prevtoken=_curtoken;
+ _curtoken=_SC('\n');
+ NEXT();
+ _currentcolumn=1;
+ continue;
+ case _SC('/'):
+ NEXT();
+ switch(CUR_CHAR){
+ case _SC('*'):
+ NEXT();
+ LexBlockComment();
+ continue;
+ case _SC('/'):
+ do { NEXT(); } while (CUR_CHAR != _SC('\n') && (!IS_EOB()));
+ continue;
+ case _SC('='):
+ NEXT();
+ RETURN_TOKEN(TK_DIVEQ);
+ continue;
+ case _SC('>'):
+ NEXT();
+ RETURN_TOKEN(TK_ATTR_CLOSE);
+ continue;
+ default:
+ RETURN_TOKEN('/');
+ }
+ case _SC('='):
+ NEXT();
+ if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('=') }
+ else { NEXT(); RETURN_TOKEN(TK_EQ); }
+ case _SC('<'):
+ NEXT();
+ if ( CUR_CHAR == _SC('=') ) { NEXT(); RETURN_TOKEN(TK_LE) }
+ else if ( CUR_CHAR == _SC('-') ) { NEXT(); RETURN_TOKEN(TK_NEWSLOT); }
+ else if ( CUR_CHAR == _SC('<') ) { NEXT(); RETURN_TOKEN(TK_SHIFTL); }
+ else if ( CUR_CHAR == _SC('/') ) { NEXT(); RETURN_TOKEN(TK_ATTR_OPEN); }
+ //else if ( CUR_CHAR == _SC('[') ) { NEXT(); ReadMultilineString(); RETURN_TOKEN(TK_STRING_LITERAL); }
+ else { RETURN_TOKEN('<') }
+ case _SC('>'):
+ NEXT();
+ if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_GE);}
+ else if(CUR_CHAR == _SC('>')){
+ NEXT();
+ if(CUR_CHAR == _SC('>')){
+ NEXT();
+ RETURN_TOKEN(TK_USHIFTR);
+ }
+ RETURN_TOKEN(TK_SHIFTR);
+ }
+ else { RETURN_TOKEN('>') }
+ case _SC('!'):
+ NEXT();
+ if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('!')}
+ else { NEXT(); RETURN_TOKEN(TK_NE); }
+ case _SC('@'): {
+ SQInteger stype;
+ NEXT();
+ if(CUR_CHAR != _SC('"'))
+ Error(_SC("string expected"));
+ if((stype=ReadString('"',true))!=-1) {
+ RETURN_TOKEN(stype);
+ }
+ Error(_SC("error parsing the string"));
+ }
+ case _SC('"'):
+ case _SC('\''): {
+ SQInteger stype;
+ if((stype=ReadString(CUR_CHAR,false))!=-1){
+ RETURN_TOKEN(stype);
+ }
+ Error(_SC("error parsing the string"));
+ }
+ case _SC('{'): case _SC('}'): case _SC('('): case _SC(')'): case _SC('['): case _SC(']'):
+ case _SC(';'): case _SC(','): case _SC('?'): case _SC('^'): case _SC('~'):
+ {SQInteger ret = CUR_CHAR;
+ NEXT(); RETURN_TOKEN(ret); }
+ case _SC('.'):
+ NEXT();
+ if (CUR_CHAR != _SC('.')){ RETURN_TOKEN('.') }
+ NEXT();
+ if (CUR_CHAR != _SC('.')){ Error(_SC("invalid token '..'")); }
+ NEXT();
+ RETURN_TOKEN(TK_VARPARAMS);
+ case _SC('&'):
+ NEXT();
+ if (CUR_CHAR != _SC('&')){ RETURN_TOKEN('&') }
+ else { NEXT(); RETURN_TOKEN(TK_AND); }
+ case _SC('|'):
+ NEXT();
+ if (CUR_CHAR != _SC('|')){ RETURN_TOKEN('|') }
+ else { NEXT(); RETURN_TOKEN(TK_OR); }
+ case _SC(':'):
+ NEXT();
+ if (CUR_CHAR != _SC(':')){ RETURN_TOKEN(':') }
+ else { NEXT(); RETURN_TOKEN(TK_DOUBLE_COLON); }
+ case _SC('*'):
+ NEXT();
+ if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MULEQ);}
+ else RETURN_TOKEN('*');
+ case _SC('%'):
+ NEXT();
+ if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MODEQ);}
+ else RETURN_TOKEN('%');
+ case _SC('-'):
+ NEXT();
+ if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MINUSEQ);}
+ else if (CUR_CHAR == _SC('-')){ NEXT(); RETURN_TOKEN(TK_MINUSMINUS);}
+ else RETURN_TOKEN('-');
+ case _SC('+'):
+ NEXT();
+ if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_PLUSEQ);}
+ else if (CUR_CHAR == _SC('+')){ NEXT(); RETURN_TOKEN(TK_PLUSPLUS);}
+ else RETURN_TOKEN('+');
+ case SQUIRREL_EOB:
+ return 0;
+ default:{
+ if (scisdigit(CUR_CHAR)) {
+ SQInteger ret = ReadNumber();
+ RETURN_TOKEN(ret);
+ }
+ else if (scisalpha(CUR_CHAR) || CUR_CHAR == _SC('_')) {
+ SQInteger t = ReadID();
+ RETURN_TOKEN(t);
+ }
+ else {
+ SQInteger c = CUR_CHAR;
+ if (sciscntrl((int)c)) Error(_SC("unexpected character(control)"));
+ NEXT();
+ RETURN_TOKEN(c);
+ }
+ RETURN_TOKEN(0);
+ }
+ }
+ }
+ return 0;
+}
+
+SQInteger SQLexer::GetIDType(SQChar *s)
+{
+ SQObjectPtr t;
+ if(_keywords->Get(SQString::Create(_sharedstate, s), t)) {
+ return SQInteger(_integer(t));
+ }
+ return TK_IDENTIFIER;
+}
+
+
+SQInteger SQLexer::ReadString(SQInteger ndelim,bool verbatim)
+{
+ INIT_TEMP_STRING();
+ NEXT();
+ if(IS_EOB()) return -1;
+ for(;;) {
+ while(CUR_CHAR != ndelim) {
+ switch(CUR_CHAR) {
+ case SQUIRREL_EOB:
+ Error(_SC("unfinished string"));
+ return -1;
+ case _SC('\n'):
+ if(!verbatim) Error(_SC("newline in a constant"));
+ APPEND_CHAR(CUR_CHAR); NEXT();
+ _currentline++;
+ break;
+ case _SC('\\'):
+ if(verbatim) {
+ APPEND_CHAR('\\'); NEXT();
+ }
+ else {
+ NEXT();
+ switch(CUR_CHAR) {
+ case _SC('x'): NEXT(); {
+ if(!isxdigit(CUR_CHAR)) Error(_SC("hexadecimal number expected"));
+ const SQInteger maxdigits = 4;
+ SQChar temp[maxdigits+1];
+ SQInteger n = 0;
+ while(isxdigit(CUR_CHAR) && n < maxdigits) {
+ temp[n] = CUR_CHAR;
+ n++;
+ NEXT();
+ }
+ temp[n] = 0;
+ SQChar *sTemp;
+ APPEND_CHAR((SQChar)scstrtoul(temp,&sTemp,16));
+ }
+ break;
+ case _SC('t'): APPEND_CHAR(_SC('\t')); NEXT(); break;
+ case _SC('a'): APPEND_CHAR(_SC('\a')); NEXT(); break;
+ case _SC('b'): APPEND_CHAR(_SC('\b')); NEXT(); break;
+ case _SC('n'): APPEND_CHAR(_SC('\n')); NEXT(); break;
+ case _SC('r'): APPEND_CHAR(_SC('\r')); NEXT(); break;
+ case _SC('v'): APPEND_CHAR(_SC('\v')); NEXT(); break;
+ case _SC('f'): APPEND_CHAR(_SC('\f')); NEXT(); break;
+ case _SC('0'): APPEND_CHAR(_SC('\0')); NEXT(); break;
+ case _SC('\\'): APPEND_CHAR(_SC('\\')); NEXT(); break;
+ case _SC('"'): APPEND_CHAR(_SC('"')); NEXT(); break;
+ case _SC('\''): APPEND_CHAR(_SC('\'')); NEXT(); break;
+ default:
+ Error(_SC("unrecognised escaper char"));
+ break;
+ }
+ }
+ break;
+ default:
+ APPEND_CHAR(CUR_CHAR);
+ NEXT();
+ }
+ }
+ NEXT();
+ if(verbatim && CUR_CHAR == '"') { //double quotation
+ APPEND_CHAR(CUR_CHAR);
+ NEXT();
+ }
+ else {
+ break;
+ }
+ }
+ TERMINATE_BUFFER();
+ SQInteger len = _longstr.size()-1;
+ if(ndelim == _SC('\'')) {
+ if(len == 0) Error(_SC("empty constant"));
+ if(len > 1) Error(_SC("constant too long"));
+ _nvalue = _longstr[0];
+ return TK_INTEGER;
+ }
+ _svalue = &_longstr[0];
+ return TK_STRING_LITERAL;
+}
+
+void LexHexadecimal(const SQChar *s,SQUnsignedInteger *res)
+{
+ *res = 0;
+ while(*s != 0)
+ {
+ if(scisdigit(*s)) *res = (*res)*16+((*s++)-'0');
+ else if(scisxdigit(*s)) *res = (*res)*16+(toupper(*s++)-'A'+10);
+ else { assert(0); }
+ }
+}
+
+void LexInteger(const SQChar *s,SQUnsignedInteger *res)
+{
+ *res = 0;
+ while(*s != 0)
+ {
+ *res = (*res)*10+((*s++)-'0');
+ }
+}
+
+SQInteger scisodigit(SQInteger c) { return c >= _SC('0') && c <= _SC('7'); }
+
+void LexOctal(const SQChar *s,SQUnsignedInteger *res)
+{
+ *res = 0;
+ while(*s != 0)
+ {
+ if(scisodigit(*s)) *res = (*res)*8+((*s++)-'0');
+ else { assert(0); }
+ }
+}
+
+SQInteger isexponent(SQInteger c) { return c == 'e' || c=='E'; }
+
+
+#define MAX_HEX_DIGITS (sizeof(SQInteger)*2)
+SQInteger SQLexer::ReadNumber()
+{
+#define TINT 1
+#define TFLOAT 2
+#define THEX 3
+#define TSCIENTIFIC 4
+#define TOCTAL 5
+ SQInteger type = TINT, firstchar = CUR_CHAR;
+ SQChar *sTemp;
+ INIT_TEMP_STRING();
+ NEXT();
+ if(firstchar == _SC('0') && (toupper(CUR_CHAR) == _SC('X') || scisodigit(CUR_CHAR)) ) {
+ if(scisodigit(CUR_CHAR)) {
+ type = TOCTAL;
+ while(scisodigit(CUR_CHAR)) {
+ APPEND_CHAR(CUR_CHAR);
+ NEXT();
+ }
+ if(scisdigit(CUR_CHAR)) Error(_SC("invalid octal number"));
+ }
+ else {
+ NEXT();
+ type = THEX;
+ while(isxdigit(CUR_CHAR)) {
+ APPEND_CHAR(CUR_CHAR);
+ NEXT();
+ }
+ if(_longstr.size() > MAX_HEX_DIGITS) Error(_SC("too many digits for an Hex number"));
+ }
+ }
+ else {
+ APPEND_CHAR((int)firstchar);
+ while (CUR_CHAR == _SC('.') || scisdigit(CUR_CHAR) || isexponent(CUR_CHAR)) {
+ if(CUR_CHAR == _SC('.')) type = TFLOAT;
+ if(isexponent(CUR_CHAR)) {
+ if(type != TFLOAT) Error(_SC("invalid numeric format"));
+ type = TSCIENTIFIC;
+ APPEND_CHAR(CUR_CHAR);
+ NEXT();
+ if(CUR_CHAR == '+' || CUR_CHAR == '-'){
+ APPEND_CHAR(CUR_CHAR);
+ NEXT();
+ }
+ if(!scisdigit(CUR_CHAR)) Error(_SC("exponent expected"));
+ }
+
+ APPEND_CHAR(CUR_CHAR);
+ NEXT();
+ }
+ }
+ TERMINATE_BUFFER();
+ switch(type) {
+ case TSCIENTIFIC:
+ case TFLOAT:
+ _fvalue = (SQFloat)scstrtod(&_longstr[0],&sTemp);
+ return TK_FLOAT;
+ case TINT:
+ LexInteger(&_longstr[0],(SQUnsignedInteger *)&_nvalue);
+ return TK_INTEGER;
+ case THEX:
+ LexHexadecimal(&_longstr[0],(SQUnsignedInteger *)&_nvalue);
+ return TK_INTEGER;
+ case TOCTAL:
+ LexOctal(&_longstr[0],(SQUnsignedInteger *)&_nvalue);
+ return TK_INTEGER;
+ }
+ return 0;
+}
+
+SQInteger SQLexer::ReadID()
+{
+ SQInteger res;
+ INIT_TEMP_STRING();
+ do {
+ APPEND_CHAR(CUR_CHAR);
+ NEXT();
+ } while(scisalnum(CUR_CHAR) || CUR_CHAR == _SC('_'));
+ TERMINATE_BUFFER();
+ res = GetIDType(&_longstr[0]);
+ if(res == TK_IDENTIFIER || res == TK_CONSTRUCTOR) {
+ _svalue = &_longstr[0];
+ }
+ return res;
+}
--- /dev/null
+/* see copyright notice in squirrel.h */
+#ifndef _SQLEXER_H_
+#define _SQLEXER_H_
+
+#ifdef SQUNICODE
+typedef SQChar LexChar;
+#else
+typedef unsigned char LexChar;
+#endif
+
+struct SQLexer
+{
+ SQLexer();
+ ~SQLexer();
+ void Init(SQSharedState *ss,SQLEXREADFUNC rg,SQUserPointer up,CompilerErrorFunc efunc,void *ed);
+ void Error(const SQChar *err);
+ SQInteger Lex();
+ const SQChar *Tok2Str(SQInteger tok);
+private:
+ SQInteger GetIDType(SQChar *s);
+ SQInteger ReadString(SQInteger ndelim,bool verbatim);
+ SQInteger ReadNumber();
+ void LexBlockComment();
+ SQInteger ReadID();
+ void Next();
+ SQInteger _curtoken;
+ SQTable *_keywords;
+public:
+ SQInteger _prevtoken;
+ SQInteger _currentline;
+ SQInteger _lasttokenline;
+ SQInteger _currentcolumn;
+ const SQChar *_svalue;
+ SQInteger _nvalue;
+ SQFloat _fvalue;
+ SQLEXREADFUNC _readf;
+ SQUserPointer _up;
+ LexChar _currdata;
+ SQSharedState *_sharedstate;
+ sqvector<SQChar> _longstr;
+ CompilerErrorFunc _errfunc;
+ void *_errtarget;
+};
+
+#endif
--- /dev/null
+/*
+ see copyright notice in squirrel.h
+*/
+#include "sqpcheader.h"
+void *sq_vm_malloc(SQUnsignedInteger size){ return malloc(size); }
+
+void *sq_vm_realloc(void *p, SQUnsignedInteger oldsize, SQUnsignedInteger size){ return realloc(p, size); }
+
+void sq_vm_free(void *p, SQUnsignedInteger size){ free(p); }
--- /dev/null
+/*
+ see copyright notice in squirrel.h
+*/
+#include "sqpcheader.h"
+#include "sqvm.h"
+#include "sqstring.h"
+#include "sqarray.h"
+#include "sqtable.h"
+#include "squserdata.h"
+#include "sqfuncproto.h"
+#include "sqclass.h"
+#include "sqclosure.h"
+
+
+const SQChar *IdType2Name(SQObjectType type)
+{
+ switch(_RAW_TYPE(type))
+ {
+ case _RT_NULL:return _SC("null");
+ case _RT_INTEGER:return _SC("integer");
+ case _RT_FLOAT:return _SC("float");
+ case _RT_BOOL:return _SC("bool");
+ case _RT_STRING:return _SC("string");
+ case _RT_TABLE:return _SC("table");
+ case _RT_ARRAY:return _SC("array");
+ case _RT_GENERATOR:return _SC("generator");
+ case _RT_CLOSURE:
+ case _RT_NATIVECLOSURE:
+ return _SC("function");
+ case _RT_USERDATA:
+ case _RT_USERPOINTER:
+ return _SC("userdata");
+ case _RT_THREAD: return _SC("thread");
+ case _RT_FUNCPROTO: return _SC("function");
+ case _RT_CLASS: return _SC("class");
+ case _RT_INSTANCE: return _SC("instance");
+ case _RT_WEAKREF: return _SC("weakref");
+ default:
+ return NULL;
+ }
+}
+
+const SQChar *GetTypeName(const SQObjectPtr &obj1)
+{
+ return IdType2Name(type(obj1));
+}
+
+SQString *SQString::Create(SQSharedState *ss,const SQChar *s,SQInteger len)
+{
+ SQString *str=ADD_STRING(ss,s,len);
+ str->_sharedstate=ss;
+ return str;
+}
+
+void SQString::Release()
+{
+ REMOVE_STRING(_sharedstate,this);
+}
+
+SQInteger SQString::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval)
+{
+ SQInteger idx = (SQInteger)TranslateIndex(refpos);
+ while(idx < _len){
+ outkey = (SQInteger)idx;
+ outval = SQInteger(_val[idx]);
+ //return idx for the next iteration
+ return ++idx;
+ }
+ //nothing to iterate anymore
+ return -1;
+}
+
+SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx)
+{
+ switch(type(idx)){
+ case OT_NULL:
+ return 0;
+ case OT_INTEGER:
+ return (SQUnsignedInteger)_integer(idx);
+ default: assert(0); break;
+ }
+ return 0;
+}
+
+SQWeakRef *SQRefCounted::GetWeakRef(SQObjectType type)
+{
+ if(!_weakref) {
+ sq_new(_weakref,SQWeakRef);
+ _weakref->_obj._type = type;
+ _weakref->_obj._unVal.pRefCounted = this;
+ }
+ return _weakref;
+}
+
+SQRefCounted::~SQRefCounted()
+{
+ if(_weakref) {
+ _weakref->_obj._type = OT_NULL;
+ _weakref->_obj._unVal.pRefCounted = NULL;
+ }
+}
+
+void SQWeakRef::Release() {
+ if(ISREFCOUNTED(_obj._type)) {
+ _obj._unVal.pRefCounted->_weakref = NULL;
+ }
+ sq_delete(this,SQWeakRef);
+}
+
+bool SQDelegable::GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res) {
+ if(_delegate) {
+ return _delegate->Get((*_ss(v)->_metamethods)[mm],res);
+ }
+ return false;
+}
+
+bool SQDelegable::SetDelegate(SQTable *mt)
+{
+ SQTable *temp = mt;
+ if(temp == this) return false;
+ while (temp) {
+ if (temp->_delegate == this) return false; //cycle detected
+ temp = temp->_delegate;
+ }
+ if (mt) __ObjAddRef(mt);
+ __ObjRelease(_delegate);
+ _delegate = mt;
+ return true;
+}
+
+bool SQGenerator::Yield(SQVM *v)
+{
+ if(_state==eSuspended) { v->Raise_Error(_SC("internal vm error, yielding dead generator")); return false;}
+ if(_state==eDead) { v->Raise_Error(_SC("internal vm error, yielding a dead generator")); return false; }
+ SQInteger size = v->_top-v->_stackbase;
+ _ci=*v->ci;
+ _stack.resize(size);
+ for(SQInteger n =0; n<size; n++) {
+ _stack._vals[n] = v->_stack[v->_stackbase+n];
+ v->_stack[v->_stackbase+n] = _null_;
+ }
+ SQInteger nvargs = v->ci->_vargs.size;
+ SQInteger vargsbase = v->ci->_vargs.base;
+ for(SQInteger j = nvargs - 1; j >= 0; j--) {
+ _vargsstack.push_back(v->_vargsstack[vargsbase+j]);
+ }
+ _ci._generator=NULL;
+ for(SQInteger i=0;i<_ci._etraps;i++) {
+ _etraps.push_back(v->_etraps.top());
+ v->_etraps.pop_back();
+ }
+ _state=eSuspended;
+ return true;
+}
+
+bool SQGenerator::Resume(SQVM *v,SQInteger target)
+{
+ SQInteger size=_stack.size();
+ if(_state==eDead){ v->Raise_Error(_SC("resuming dead generator")); return false; }
+ if(_state==eRunning){ v->Raise_Error(_SC("resuming active generator")); return false; }
+ SQInteger prevtop=v->_top-v->_stackbase;
+ PUSH_CALLINFO(v,_ci);
+ SQInteger oldstackbase=v->_stackbase;
+ v->_stackbase = v->_top;
+ v->ci->_target = (SQInt32)target;
+ v->ci->_generator = this;
+ v->ci->_vargs.size = (unsigned short)_vargsstack.size();
+
+ for(SQInteger i=0;i<_ci._etraps;i++) {
+ v->_etraps.push_back(_etraps.top());
+ _etraps.pop_back();
+ }
+ for(SQInteger n =0; n<size; n++) {
+ v->_stack[v->_stackbase+n] = _stack._vals[n];
+ _stack._vals[0] = _null_;
+ }
+ while(_vargsstack.size()) {
+ v->_vargsstack.push_back(_vargsstack.back());
+ _vargsstack.pop_back();
+ }
+ v->ci->_vargs.base = (unsigned short)(v->_vargsstack.size() - v->ci->_vargs.size);
+ v->_top=v->_stackbase+size;
+ v->ci->_prevtop = (SQInt32)prevtop;
+ v->ci->_prevstkbase = (SQInt32)(v->_stackbase - oldstackbase);
+ _state=eRunning;
+ if (type(v->_debughook) != OT_NULL && _rawval(v->_debughook) != _rawval(v->ci->_closure))
+ v->CallDebugHook(_SC('c'));
+
+ return true;
+}
+
+void SQArray::Extend(const SQArray *a){
+ SQInteger xlen;
+ if((xlen=a->Size()))
+ for(SQInteger i=0;i<xlen;i++)
+ Append(a->_values[i]);
+}
+
+const SQChar* SQFunctionProto::GetLocal(SQVM *vm,SQUnsignedInteger stackbase,SQUnsignedInteger nseq,SQUnsignedInteger nop)
+{
+ SQUnsignedInteger nvars=_nlocalvarinfos;
+ const SQChar *res=NULL;
+ if(nvars>=nseq){
+ for(SQUnsignedInteger i=0;i<nvars;i++){
+ if(_localvarinfos[i]._start_op<=nop && _localvarinfos[i]._end_op>=nop)
+ {
+ if(nseq==0){
+ vm->Push(vm->_stack[stackbase+_localvarinfos[i]._pos]);
+ res=_stringval(_localvarinfos[i]._name);
+ break;
+ }
+ nseq--;
+ }
+ }
+ }
+ return res;
+}
+
+SQInteger SQFunctionProto::GetLine(SQInstruction *curr)
+{
+ SQInteger op = (SQInteger)(curr-_instructions);
+ SQInteger line=_lineinfos[0]._line;
+ for(SQInteger i=1;i<_nlineinfos;i++){
+ if(_lineinfos[i]._op>=op)
+ return line;
+ line=_lineinfos[i]._line;
+ }
+ return line;
+}
+
+#define _CHECK_IO(exp) { if(!exp)return false; }
+bool SafeWrite(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,SQUserPointer dest,SQInteger size)
+{
+ if(write(up,dest,size) != size) {
+ v->Raise_Error(_SC("io error (write function failure)"));
+ return false;
+ }
+ return true;
+}
+
+bool SafeRead(HSQUIRRELVM v,SQWRITEFUNC read,SQUserPointer up,SQUserPointer dest,SQInteger size)
+{
+ if(size && read(up,dest,size) != size) {
+ v->Raise_Error(_SC("io error, read function failure, the origin stream could be corrupted/trucated"));
+ return false;
+ }
+ return true;
+}
+
+bool WriteTag(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,SQInteger tag)
+{
+ return SafeWrite(v,write,up,&tag,sizeof(tag));
+}
+
+bool CheckTag(HSQUIRRELVM v,SQWRITEFUNC read,SQUserPointer up,SQInteger tag)
+{
+ SQInteger t;
+ _CHECK_IO(SafeRead(v,read,up,&t,sizeof(t)));
+ if(t != tag){
+ v->Raise_Error(_SC("invalid or corrupted closure stream"));
+ return false;
+ }
+ return true;
+}
+
+bool WriteObject(HSQUIRRELVM v,SQUserPointer up,SQWRITEFUNC write,SQObjectPtr &o)
+{
+ _CHECK_IO(SafeWrite(v,write,up,&type(o),sizeof(SQObjectType)));
+ switch(type(o)){
+ case OT_STRING:
+ _CHECK_IO(SafeWrite(v,write,up,&_string(o)->_len,sizeof(SQInteger)));
+ _CHECK_IO(SafeWrite(v,write,up,_stringval(o),rsl(_string(o)->_len)));
+ break;
+ case OT_INTEGER:
+ _CHECK_IO(SafeWrite(v,write,up,&_integer(o),sizeof(SQInteger)));break;
+ case OT_FLOAT:
+ _CHECK_IO(SafeWrite(v,write,up,&_float(o),sizeof(SQFloat)));break;
+ case OT_NULL:
+ break;
+ default:
+ v->Raise_Error(_SC("cannot serialize a %s"),GetTypeName(o));
+ return false;
+ }
+ return true;
+}
+
+bool ReadObject(HSQUIRRELVM v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &o)
+{
+ SQObjectType t;
+ _CHECK_IO(SafeRead(v,read,up,&t,sizeof(SQObjectType)));
+ switch(t){
+ case OT_STRING:{
+ SQInteger len;
+ _CHECK_IO(SafeRead(v,read,up,&len,sizeof(SQInteger)));
+ _CHECK_IO(SafeRead(v,read,up,_ss(v)->GetScratchPad(rsl(len)),rsl(len)));
+ o=SQString::Create(_ss(v),_ss(v)->GetScratchPad(-1),len);
+ }
+ break;
+ case OT_INTEGER:{
+ SQInteger i;
+ _CHECK_IO(SafeRead(v,read,up,&i,sizeof(SQInteger))); o = i; break;
+ }
+ case OT_FLOAT:{
+ SQFloat f;
+ _CHECK_IO(SafeRead(v,read,up,&f,sizeof(SQFloat))); o = f; break;
+ }
+ case OT_NULL:
+ o=_null_;
+ break;
+ default:
+ v->Raise_Error(_SC("cannot serialize a %s"),IdType2Name(t));
+ return false;
+ }
+ return true;
+}
+
+bool SQClosure::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write)
+{
+ _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_HEAD));
+ _CHECK_IO(WriteTag(v,write,up,sizeof(SQChar)));
+ _CHECK_IO(_funcproto(_function)->Save(v,up,write));
+ _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_TAIL));
+ return true;
+}
+
+bool SQClosure::Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret)
+{
+ _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_HEAD));
+ _CHECK_IO(CheckTag(v,read,up,sizeof(SQChar)));
+ SQObjectPtr func;
+ _CHECK_IO(SQFunctionProto::Load(v,up,read,func));
+ _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_TAIL));
+ ret = SQClosure::Create(_ss(v),_funcproto(func));
+ return true;
+}
+
+bool SQFunctionProto::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write)
+{
+ SQInteger i,nliterals = _nliterals,nparameters = _nparameters;
+ SQInteger noutervalues = _noutervalues,nlocalvarinfos = _nlocalvarinfos;
+ SQInteger nlineinfos=_nlineinfos,ninstructions = _ninstructions,nfunctions=_nfunctions;
+ SQInteger ndefaultparams = _ndefaultparams;
+ _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
+ _CHECK_IO(WriteObject(v,up,write,_sourcename));
+ _CHECK_IO(WriteObject(v,up,write,_name));
+ _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
+ _CHECK_IO(SafeWrite(v,write,up,&nliterals,sizeof(nliterals)));
+ _CHECK_IO(SafeWrite(v,write,up,&nparameters,sizeof(nparameters)));
+ _CHECK_IO(SafeWrite(v,write,up,&noutervalues,sizeof(noutervalues)));
+ _CHECK_IO(SafeWrite(v,write,up,&nlocalvarinfos,sizeof(nlocalvarinfos)));
+ _CHECK_IO(SafeWrite(v,write,up,&nlineinfos,sizeof(nlineinfos)));
+ _CHECK_IO(SafeWrite(v,write,up,&ndefaultparams,sizeof(ndefaultparams)));
+ _CHECK_IO(SafeWrite(v,write,up,&ninstructions,sizeof(ninstructions)));
+ _CHECK_IO(SafeWrite(v,write,up,&nfunctions,sizeof(nfunctions)));
+ _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
+ for(i=0;i<nliterals;i++){
+ _CHECK_IO(WriteObject(v,up,write,_literals[i]));
+ }
+
+ _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
+ for(i=0;i<nparameters;i++){
+ _CHECK_IO(WriteObject(v,up,write,_parameters[i]));
+ }
+
+ _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
+ for(i=0;i<noutervalues;i++){
+ _CHECK_IO(SafeWrite(v,write,up,&_outervalues[i]._type,sizeof(SQUnsignedInteger)));
+ _CHECK_IO(WriteObject(v,up,write,_outervalues[i]._src));
+ _CHECK_IO(WriteObject(v,up,write,_outervalues[i]._name));
+ }
+
+ _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
+ for(i=0;i<nlocalvarinfos;i++){
+ SQLocalVarInfo &lvi=_localvarinfos[i];
+ _CHECK_IO(WriteObject(v,up,write,lvi._name));
+ _CHECK_IO(SafeWrite(v,write,up,&lvi._pos,sizeof(SQUnsignedInteger)));
+ _CHECK_IO(SafeWrite(v,write,up,&lvi._start_op,sizeof(SQUnsignedInteger)));
+ _CHECK_IO(SafeWrite(v,write,up,&lvi._end_op,sizeof(SQUnsignedInteger)));
+ }
+
+ _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
+ _CHECK_IO(SafeWrite(v,write,up,_lineinfos,sizeof(SQLineInfo)*nlineinfos));
+
+ _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
+ _CHECK_IO(SafeWrite(v,write,up,_defaultparams,sizeof(SQInteger)*ndefaultparams));
+
+ _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
+ _CHECK_IO(SafeWrite(v,write,up,_instructions,sizeof(SQInstruction)*ninstructions));
+
+ _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
+ for(i=0;i<nfunctions;i++){
+ _CHECK_IO(_funcproto(_functions[i])->Save(v,up,write));
+ }
+ _CHECK_IO(SafeWrite(v,write,up,&_stacksize,sizeof(_stacksize)));
+ _CHECK_IO(SafeWrite(v,write,up,&_bgenerator,sizeof(_bgenerator)));
+ _CHECK_IO(SafeWrite(v,write,up,&_varparams,sizeof(_varparams)));
+ return true;
+}
+
+bool SQFunctionProto::Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret)
+{
+ SQInteger i, nliterals,nparameters;
+ SQInteger noutervalues ,nlocalvarinfos ;
+ SQInteger nlineinfos,ninstructions ,nfunctions,ndefaultparams ;
+ SQObjectPtr sourcename, name;
+ SQObjectPtr o;
+ _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
+ _CHECK_IO(ReadObject(v, up, read, sourcename));
+ _CHECK_IO(ReadObject(v, up, read, name));
+
+ _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
+ _CHECK_IO(SafeRead(v,read,up, &nliterals, sizeof(nliterals)));
+ _CHECK_IO(SafeRead(v,read,up, &nparameters, sizeof(nparameters)));
+ _CHECK_IO(SafeRead(v,read,up, &noutervalues, sizeof(noutervalues)));
+ _CHECK_IO(SafeRead(v,read,up, &nlocalvarinfos, sizeof(nlocalvarinfos)));
+ _CHECK_IO(SafeRead(v,read,up, &nlineinfos, sizeof(nlineinfos)));
+ _CHECK_IO(SafeRead(v,read,up, &ndefaultparams, sizeof(ndefaultparams)));
+ _CHECK_IO(SafeRead(v,read,up, &ninstructions, sizeof(ninstructions)));
+ _CHECK_IO(SafeRead(v,read,up, &nfunctions, sizeof(nfunctions)));
+
+
+ SQFunctionProto *f = SQFunctionProto::Create(ninstructions,nliterals,nparameters,
+ nfunctions,noutervalues,nlineinfos,nlocalvarinfos,ndefaultparams);
+ SQObjectPtr proto = f; //gets a ref in case of failure
+ f->_sourcename = sourcename;
+ f->_name = name;
+
+ _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
+
+ for(i = 0;i < nliterals; i++){
+ _CHECK_IO(ReadObject(v, up, read, o));
+ f->_literals[i] = o;
+ }
+ _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
+
+ for(i = 0; i < nparameters; i++){
+ _CHECK_IO(ReadObject(v, up, read, o));
+ f->_parameters[i] = o;
+ }
+ _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
+
+ for(i = 0; i < noutervalues; i++){
+ SQUnsignedInteger type;
+ SQObjectPtr name;
+ _CHECK_IO(SafeRead(v,read,up, &type, sizeof(SQUnsignedInteger)));
+ _CHECK_IO(ReadObject(v, up, read, o));
+ _CHECK_IO(ReadObject(v, up, read, name));
+ f->_outervalues[i] = SQOuterVar(name,o, (SQOuterType)type);
+ }
+ _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
+
+ for(i = 0; i < nlocalvarinfos; i++){
+ SQLocalVarInfo lvi;
+ _CHECK_IO(ReadObject(v, up, read, lvi._name));
+ _CHECK_IO(SafeRead(v,read,up, &lvi._pos, sizeof(SQUnsignedInteger)));
+ _CHECK_IO(SafeRead(v,read,up, &lvi._start_op, sizeof(SQUnsignedInteger)));
+ _CHECK_IO(SafeRead(v,read,up, &lvi._end_op, sizeof(SQUnsignedInteger)));
+ f->_localvarinfos[i] = lvi;
+ }
+ _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
+ _CHECK_IO(SafeRead(v,read,up, f->_lineinfos, sizeof(SQLineInfo)*nlineinfos));
+
+ _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
+ _CHECK_IO(SafeRead(v,read,up, f->_defaultparams, sizeof(SQInteger)*ndefaultparams));
+
+ _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
+ _CHECK_IO(SafeRead(v,read,up, f->_instructions, sizeof(SQInstruction)*ninstructions));
+
+ _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
+ for(i = 0; i < nfunctions; i++){
+ _CHECK_IO(_funcproto(o)->Load(v, up, read, o));
+ f->_functions[i] = o;
+ }
+ _CHECK_IO(SafeRead(v,read,up, &f->_stacksize, sizeof(f->_stacksize)));
+ _CHECK_IO(SafeRead(v,read,up, &f->_bgenerator, sizeof(f->_bgenerator)));
+ _CHECK_IO(SafeRead(v,read,up, &f->_varparams, sizeof(f->_varparams)));
+
+ ret = f;
+ return true;
+}
+
+#ifndef NO_GARBAGE_COLLECTOR
+
+#define START_MARK() if(!(_uiRef&MARK_FLAG)){ \
+ _uiRef|=MARK_FLAG;
+
+#define END_MARK() RemoveFromChain(&_sharedstate->_gc_chain, this); \
+ AddToChain(chain, this); }
+
+void SQVM::Mark(SQCollectable **chain)
+{
+ START_MARK()
+ SQSharedState::MarkObject(_lasterror,chain);
+ SQSharedState::MarkObject(_errorhandler,chain);
+ SQSharedState::MarkObject(_debughook,chain);
+ SQSharedState::MarkObject(_roottable, chain);
+ SQSharedState::MarkObject(temp_reg, chain);
+ for(SQUnsignedInteger i = 0; i < _stack.size(); i++) SQSharedState::MarkObject(_stack[i], chain);
+ for(SQUnsignedInteger j = 0; j < _vargsstack.size(); j++) SQSharedState::MarkObject(_vargsstack[j], chain);
+ for(SQInteger k = 0; k < _callsstacksize; k++) SQSharedState::MarkObject(_callsstack[k]._closure, chain);
+ END_MARK()
+}
+
+void SQArray::Mark(SQCollectable **chain)
+{
+ START_MARK()
+ SQInteger len = _values.size();
+ for(SQInteger i = 0;i < len; i++) SQSharedState::MarkObject(_values[i], chain);
+ END_MARK()
+}
+void SQTable::Mark(SQCollectable **chain)
+{
+ START_MARK()
+ if(_delegate) _delegate->Mark(chain);
+ SQInteger len = _numofnodes;
+ for(SQInteger i = 0; i < len; i++){
+ SQSharedState::MarkObject(_nodes[i].key, chain);
+ SQSharedState::MarkObject(_nodes[i].val, chain);
+ }
+ END_MARK()
+}
+
+void SQClass::Mark(SQCollectable **chain)
+{
+ START_MARK()
+ _members->Mark(chain);
+ if(_base) _base->Mark(chain);
+ SQSharedState::MarkObject(_attributes, chain);
+ for(SQUnsignedInteger i =0; i< _defaultvalues.size(); i++) {
+ SQSharedState::MarkObject(_defaultvalues[i].val, chain);
+ SQSharedState::MarkObject(_defaultvalues[i].attrs, chain);
+ }
+ for(SQUnsignedInteger j =0; j< _methods.size(); j++) {
+ SQSharedState::MarkObject(_methods[j].val, chain);
+ SQSharedState::MarkObject(_methods[j].attrs, chain);
+ }
+ for(SQUnsignedInteger k =0; k< _metamethods.size(); k++) {
+ SQSharedState::MarkObject(_metamethods[k], chain);
+ }
+ END_MARK()
+}
+
+void SQInstance::Mark(SQCollectable **chain)
+{
+ START_MARK()
+ _class->Mark(chain);
+ SQUnsignedInteger nvalues = _class->_defaultvalues.size();
+ for(SQUnsignedInteger i =0; i< nvalues; i++) {
+ SQSharedState::MarkObject(_values[i], chain);
+ }
+ END_MARK()
+}
+
+void SQGenerator::Mark(SQCollectable **chain)
+{
+ START_MARK()
+ for(SQUnsignedInteger i = 0; i < _stack.size(); i++) SQSharedState::MarkObject(_stack[i], chain);
+ for(SQUnsignedInteger j = 0; j < _vargsstack.size(); j++) SQSharedState::MarkObject(_vargsstack[j], chain);
+ SQSharedState::MarkObject(_closure, chain);
+ END_MARK()
+}
+
+void SQClosure::Mark(SQCollectable **chain)
+{
+ START_MARK()
+ for(SQUnsignedInteger i = 0; i < _outervalues.size(); i++) SQSharedState::MarkObject(_outervalues[i], chain);
+ for(SQUnsignedInteger i = 0; i < _defaultparams.size(); i++) SQSharedState::MarkObject(_defaultparams[i], chain);
+ END_MARK()
+}
+
+void SQNativeClosure::Mark(SQCollectable **chain)
+{
+ START_MARK()
+ for(SQUnsignedInteger i = 0; i < _outervalues.size(); i++) SQSharedState::MarkObject(_outervalues[i], chain);
+ END_MARK()
+}
+
+void SQUserData::Mark(SQCollectable **chain){
+ START_MARK()
+ if(_delegate) _delegate->Mark(chain);
+ END_MARK()
+}
+
+void SQCollectable::UnMark() { _uiRef&=~MARK_FLAG; }
+
+#endif
+
--- /dev/null
+/* see copyright notice in squirrel.h */
+#ifndef _SQOBJECT_H_
+#define _SQOBJECT_H_
+
+#include "squtils.h"
+
+#define SQ_CLOSURESTREAM_HEAD (('S'<<24)|('Q'<<16)|('I'<<8)|('R'))
+#define SQ_CLOSURESTREAM_PART (('P'<<24)|('A'<<16)|('R'<<8)|('T'))
+#define SQ_CLOSURESTREAM_TAIL (('T'<<24)|('A'<<16)|('I'<<8)|('L'))
+
+struct SQSharedState;
+
+enum SQMetaMethod{
+ MT_ADD=0,
+ MT_SUB=1,
+ MT_MUL=2,
+ MT_DIV=3,
+ MT_UNM=4,
+ MT_MODULO=5,
+ MT_SET=6,
+ MT_GET=7,
+ MT_TYPEOF=8,
+ MT_NEXTI=9,
+ MT_CMP=10,
+ MT_CALL=11,
+ MT_CLONED=12,
+ MT_NEWSLOT=13,
+ MT_DELSLOT=14,
+ MT_TOSTRING=15,
+ MT_NEWMEMBER=16,
+ MT_INHERITED=17,
+ MT_LAST = 18
+};
+
+#define MM_ADD _SC("_add")
+#define MM_SUB _SC("_sub")
+#define MM_MUL _SC("_mul")
+#define MM_DIV _SC("_div")
+#define MM_UNM _SC("_unm")
+#define MM_MODULO _SC("_modulo")
+#define MM_SET _SC("_set")
+#define MM_GET _SC("_get")
+#define MM_TYPEOF _SC("_typeof")
+#define MM_NEXTI _SC("_nexti")
+#define MM_CMP _SC("_cmp")
+#define MM_CALL _SC("_call")
+#define MM_CLONED _SC("_cloned")
+#define MM_NEWSLOT _SC("_newslot")
+#define MM_DELSLOT _SC("_delslot")
+#define MM_TOSTRING _SC("_tostring")
+#define MM_NEWMEMBER _SC("_newmember")
+#define MM_INHERITED _SC("_inherited")
+
+#define MINPOWER2 4
+
+struct SQRefCounted
+{
+ SQRefCounted() { _uiRef = 0; _weakref = NULL; }
+ virtual ~SQRefCounted();
+ SQWeakRef *GetWeakRef(SQObjectType type);
+ SQUnsignedInteger _uiRef;
+ struct SQWeakRef *_weakref;
+ virtual void Release()=0;
+};
+
+struct SQWeakRef : SQRefCounted
+{
+ void Release();
+ SQObject _obj;
+};
+
+#define _realval(o) (type((o)) != OT_WEAKREF?(SQObject)o:_weakref(o)->_obj)
+
+struct SQObjectPtr;
+
+#define __AddRef(type,unval) if(ISREFCOUNTED(type)) \
+ { \
+ unval.pRefCounted->_uiRef++; \
+ }
+
+#define __Release(type,unval) if(ISREFCOUNTED(type) && ((--unval.pRefCounted->_uiRef)<=0)) \
+ { \
+ unval.pRefCounted->Release(); \
+ }
+
+#define __ObjRelease(obj) { \
+ if((obj)) { \
+ (obj)->_uiRef--; \
+ if((obj)->_uiRef == 0) \
+ (obj)->Release(); \
+ (obj) = NULL; \
+ } \
+}
+
+#define __ObjAddRef(obj) { \
+ (obj)->_uiRef++; \
+}
+
+#define type(obj) ((obj)._type)
+#define is_delegable(t) (type(t)&SQOBJECT_DELEGABLE)
+#define raw_type(obj) _RAW_TYPE((obj)._type)
+
+#define _integer(obj) ((obj)._unVal.nInteger)
+#define _float(obj) ((obj)._unVal.fFloat)
+#define _string(obj) ((obj)._unVal.pString)
+#define _table(obj) ((obj)._unVal.pTable)
+#define _array(obj) ((obj)._unVal.pArray)
+#define _closure(obj) ((obj)._unVal.pClosure)
+#define _generator(obj) ((obj)._unVal.pGenerator)
+#define _nativeclosure(obj) ((obj)._unVal.pNativeClosure)
+#define _userdata(obj) ((obj)._unVal.pUserData)
+#define _userpointer(obj) ((obj)._unVal.pUserPointer)
+#define _thread(obj) ((obj)._unVal.pThread)
+#define _funcproto(obj) ((obj)._unVal.pFunctionProto)
+#define _class(obj) ((obj)._unVal.pClass)
+#define _instance(obj) ((obj)._unVal.pInstance)
+#define _delegable(obj) ((SQDelegable *)(obj)._unVal.pDelegable)
+#define _weakref(obj) ((obj)._unVal.pWeakRef)
+#define _refcounted(obj) ((obj)._unVal.pRefCounted)
+#define _rawval(obj) ((obj)._unVal.raw)
+
+#define _stringval(obj) (obj)._unVal.pString->_val
+#define _userdataval(obj) (obj)._unVal.pUserData->_val
+
+#define tofloat(num) ((type(num)==OT_INTEGER)?(SQFloat)_integer(num):_float(num))
+#define tointeger(num) ((type(num)==OT_FLOAT)?(SQInteger)_float(num):_integer(num))
+/////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////
+struct SQObjectPtr : public SQObject
+{
+ SQObjectPtr()
+ {
+ SQ_OBJECT_RAWINIT()
+ _type=OT_NULL;
+ _unVal.pUserPointer=NULL;
+ }
+ SQObjectPtr(const SQObjectPtr &o)
+ {
+ SQ_OBJECT_RAWINIT()
+ _type=o._type;
+ _unVal=o._unVal;
+ __AddRef(_type,_unVal);
+ }
+ SQObjectPtr(const SQObject &o)
+ {
+ SQ_OBJECT_RAWINIT()
+ _type=o._type;
+ _unVal=o._unVal;
+ __AddRef(_type,_unVal);
+ }
+ SQObjectPtr(SQTable *pTable)
+ {
+ SQ_OBJECT_RAWINIT()
+ _type=OT_TABLE;
+ _unVal.pTable=pTable;
+ assert(_unVal.pTable);
+ __AddRef(_type,_unVal);
+ }
+ SQObjectPtr(SQClass *pClass)
+ {
+ SQ_OBJECT_RAWINIT()
+ _type=OT_CLASS;
+ _unVal.pClass=pClass;
+ assert(_unVal.pClass);
+ __AddRef(_type,_unVal);
+ }
+ SQObjectPtr(SQInstance *pInstance)
+ {
+ SQ_OBJECT_RAWINIT()
+ _type=OT_INSTANCE;
+ _unVal.pInstance=pInstance;
+ assert(_unVal.pInstance);
+ __AddRef(_type,_unVal);
+ }
+ SQObjectPtr(SQArray *pArray)
+ {
+ SQ_OBJECT_RAWINIT()
+ _type=OT_ARRAY;
+ _unVal.pArray=pArray;
+ assert(_unVal.pArray);
+ __AddRef(_type,_unVal);
+ }
+ SQObjectPtr(SQClosure *pClosure)
+ {
+ SQ_OBJECT_RAWINIT()
+ _type=OT_CLOSURE;
+ _unVal.pClosure=pClosure;
+ assert(_unVal.pClosure);
+ __AddRef(_type,_unVal);
+ }
+ SQObjectPtr(SQGenerator *pGenerator)
+ {
+ SQ_OBJECT_RAWINIT()
+ _type=OT_GENERATOR;
+ _unVal.pGenerator=pGenerator;
+ assert(_unVal.pGenerator);
+ __AddRef(_type,_unVal);
+ }
+ SQObjectPtr(SQNativeClosure *pNativeClosure)
+ {
+ SQ_OBJECT_RAWINIT()
+ _type=OT_NATIVECLOSURE;
+ _unVal.pNativeClosure=pNativeClosure;
+ assert(_unVal.pNativeClosure);
+ __AddRef(_type,_unVal);
+ }
+ SQObjectPtr(SQString *pString)
+ {
+ SQ_OBJECT_RAWINIT()
+ _type=OT_STRING;
+ _unVal.pString=pString;
+ assert(_unVal.pString);
+ __AddRef(_type,_unVal);
+ }
+ SQObjectPtr(SQUserData *pUserData)
+ {
+ SQ_OBJECT_RAWINIT()
+ _type=OT_USERDATA;
+ _unVal.pUserData=pUserData;
+ assert(_unVal.pUserData);
+ __AddRef(_type,_unVal);
+ }
+ SQObjectPtr(SQVM *pThread)
+ {
+ SQ_OBJECT_RAWINIT()
+ _type=OT_THREAD;
+ _unVal.pThread=pThread;
+ assert(_unVal.pThread);
+ __AddRef(_type,_unVal);
+ }
+ SQObjectPtr(SQWeakRef *pWeakRef)
+ {
+ SQ_OBJECT_RAWINIT()
+ _type=OT_WEAKREF;
+ _unVal.pWeakRef=pWeakRef;
+ assert(_unVal.pWeakRef);
+ __AddRef(_type,_unVal);
+ }
+ SQObjectPtr(SQFunctionProto *pFunctionProto)
+ {
+ SQ_OBJECT_RAWINIT()
+ _type=OT_FUNCPROTO;
+ _unVal.pFunctionProto=pFunctionProto;
+ assert(_unVal.pFunctionProto);
+ __AddRef(_type,_unVal);
+ }
+ SQObjectPtr(SQInteger nInteger)
+ {
+ SQ_OBJECT_RAWINIT()
+ _type=OT_INTEGER;
+ _unVal.nInteger=nInteger;
+ }
+ SQObjectPtr(SQFloat fFloat)
+ {
+ SQ_OBJECT_RAWINIT()
+ _type=OT_FLOAT;
+ _unVal.fFloat=fFloat;
+ }
+ SQObjectPtr(bool bBool)
+ {
+ SQ_OBJECT_RAWINIT()
+ _type = OT_BOOL;
+ _unVal.nInteger = bBool?1:0;
+ }
+ SQObjectPtr(SQUserPointer pUserPointer)
+ {
+ SQ_OBJECT_RAWINIT()
+ _type=OT_USERPOINTER;
+ _unVal.pUserPointer=pUserPointer;
+ }
+ ~SQObjectPtr()
+ {
+ __Release(_type,_unVal);
+ }
+ inline void Null()
+ {
+ SQObjectType tOldType;
+ SQObjectValue unOldVal;
+ tOldType = _type;
+ unOldVal = _unVal;
+ _type = OT_NULL;
+ _unVal.pUserPointer = NULL;
+ __Release(tOldType,unOldVal);
+ }
+ inline SQObjectPtr& operator=(SQInteger i)
+ {
+ __Release(_type,_unVal);
+ _unVal.nInteger = i;
+ _type = OT_INTEGER;
+ return *this;
+ }
+ inline SQObjectPtr& operator=(SQFloat f)
+ {
+ __Release(_type,_unVal);
+ _unVal.fFloat = f;
+ _type = OT_FLOAT;
+ return *this;
+ }
+ inline SQObjectPtr& operator=(const SQObjectPtr& obj)
+ {
+ SQObjectType tOldType;
+ SQObjectValue unOldVal;
+ tOldType=_type;
+ unOldVal=_unVal;
+ _unVal = obj._unVal;
+ _type = obj._type;
+ __AddRef(_type,_unVal);
+ __Release(tOldType,unOldVal);
+ return *this;
+ }
+ inline SQObjectPtr& operator=(const SQObject& obj)
+ {
+ SQObjectType tOldType;
+ SQObjectValue unOldVal;
+ tOldType=_type;
+ unOldVal=_unVal;
+ _unVal = obj._unVal;
+ _type = obj._type;
+ __AddRef(_type,_unVal);
+ __Release(tOldType,unOldVal);
+ return *this;
+ }
+ private:
+ SQObjectPtr(const SQChar *){} //safety
+};
+/////////////////////////////////////////////////////////////////////////////////////
+#ifndef NO_GARBAGE_COLLECTOR
+#define MARK_FLAG 0x80000000
+struct SQCollectable : public SQRefCounted {
+ SQCollectable *_next;
+ SQCollectable *_prev;
+ SQSharedState *_sharedstate;
+ virtual void Release()=0;
+ virtual void Mark(SQCollectable **chain)=0;
+ void UnMark();
+ virtual void Finalize()=0;
+ static void AddToChain(SQCollectable **chain,SQCollectable *c);
+ static void RemoveFromChain(SQCollectable **chain,SQCollectable *c);
+};
+
+
+#define ADD_TO_CHAIN(chain,obj) AddToChain(chain,obj)
+#define REMOVE_FROM_CHAIN(chain,obj) {if(!(_uiRef&MARK_FLAG))RemoveFromChain(chain,obj);}
+#define CHAINABLE_OBJ SQCollectable
+#define INIT_CHAIN() {_next=NULL;_prev=NULL;_sharedstate=ss;}
+#else
+
+#define ADD_TO_CHAIN(chain,obj) ((void)0)
+#define REMOVE_FROM_CHAIN(chain,obj) ((void)0)
+#define CHAINABLE_OBJ SQRefCounted
+#define INIT_CHAIN() ((void)0)
+#endif
+
+struct SQDelegable : public CHAINABLE_OBJ {
+ bool SetDelegate(SQTable *m);
+ virtual bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res);
+ SQTable *_delegate;
+};
+
+SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx);
+typedef sqvector<SQObjectPtr> SQObjectPtrVec;
+typedef sqvector<SQInteger> SQIntVec;
+const SQChar *GetTypeName(const SQObjectPtr &obj1);
+const SQChar *IdType2Name(SQObjectType type);
+
+
+
+#endif //_SQOBJECT_H_
--- /dev/null
+/* see copyright notice in squirrel.h */
+#ifndef _SQOPCODES_H_
+#define _SQOPCODES_H_
+
+#define MAX_FUNC_STACKSIZE 0xFF
+#define MAX_LITERALS ((SQInteger)0x7FFFFFFF)
+
+enum BitWiseOP {
+ BW_AND = 0,
+ BW_OR = 2,
+ BW_XOR = 3,
+ BW_SHIFTL = 4,
+ BW_SHIFTR = 5,
+ BW_USHIFTR = 6
+};
+
+enum CmpOP {
+ CMP_G = 0,
+ CMP_GE = 2,
+ CMP_L = 3,
+ CMP_LE = 4
+};
+enum SQOpcode
+{
+ _OP_LINE= 0x00,
+ _OP_LOAD= 0x01,
+ _OP_LOADINT= 0x02,
+ _OP_LOADFLOAT= 0x03,
+ _OP_DLOAD= 0x04,
+ _OP_TAILCALL= 0x05,
+ _OP_CALL= 0x06,
+ _OP_PREPCALL= 0x07,
+ _OP_PREPCALLK= 0x08,
+ _OP_GETK= 0x09,
+ _OP_MOVE= 0x0A,
+ _OP_NEWSLOT= 0x0B,
+ _OP_DELETE= 0x0C,
+ _OP_SET= 0x0D,
+ _OP_GET= 0x0E,
+ _OP_EQ= 0x0F,
+ _OP_NE= 0x10,
+ _OP_ARITH= 0x11,
+ _OP_BITW= 0x12,
+ _OP_RETURN= 0x13,
+ _OP_LOADNULLS= 0x14,
+ _OP_LOADROOTTABLE= 0x15,
+ _OP_LOADBOOL= 0x16,
+ _OP_DMOVE= 0x17,
+ _OP_JMP= 0x18,
+ _OP_JNZ= 0x19,
+ _OP_JZ= 0x1A,
+ _OP_LOADFREEVAR= 0x1B,
+ _OP_VARGC= 0x1C,
+ _OP_GETVARGV= 0x1D,
+ _OP_NEWTABLE= 0x1E,
+ _OP_NEWARRAY= 0x1F,
+ _OP_APPENDARRAY= 0x20,
+ _OP_GETPARENT= 0x21,
+ _OP_COMPARITH= 0x22,
+ _OP_COMPARITHL= 0x23,
+ _OP_INC= 0x24,
+ _OP_INCL= 0x25,
+ _OP_PINC= 0x26,
+ _OP_PINCL= 0x27,
+ _OP_CMP= 0x28,
+ _OP_EXISTS= 0x29,
+ _OP_INSTANCEOF= 0x2A,
+ _OP_AND= 0x2B,
+ _OP_OR= 0x2C,
+ _OP_NEG= 0x2D,
+ _OP_NOT= 0x2E,
+ _OP_BWNOT= 0x2F,
+ _OP_CLOSURE= 0x30,
+ _OP_YIELD= 0x31,
+ _OP_RESUME= 0x32,
+ _OP_FOREACH= 0x33,
+ _OP_POSTFOREACH= 0x34,
+ _OP_DELEGATE= 0x35,
+ _OP_CLONE= 0x36,
+ _OP_TYPEOF= 0x37,
+ _OP_PUSHTRAP= 0x38,
+ _OP_POPTRAP= 0x39,
+ _OP_THROW= 0x3A,
+ _OP_CLASS= 0x3B,
+ _OP_NEWSLOTA= 0x3C,
+};
+
+struct SQInstructionDesc {
+ const SQChar *name;
+};
+
+struct SQInstruction
+{
+ SQInstruction(){};
+ SQInstruction(SQOpcode _op,SQInteger a0=0,SQInteger a1=0,SQInteger a2=0,SQInteger a3=0)
+ { op = _op;
+ _arg0 = (unsigned char)a0;_arg1 = (SQInt32)a1;
+ _arg2 = (unsigned char)a2;_arg3 = (unsigned char)a3;
+ }
+
+
+ SQInt32 _arg1;
+ unsigned char op;
+ unsigned char _arg0;
+ unsigned char _arg2;
+ unsigned char _arg3;
+};
+
+#include "squtils.h"
+typedef sqvector<SQInstruction> SQInstructionVec;
+
+#define NEW_SLOT_ATTRIBUTES_FLAG 0x01
+#define NEW_SLOT_STATIC_FLAG 0x02
+
+#endif // _SQOPCODES_H_
--- /dev/null
+/* see copyright notice in squirrel.h */
+#ifndef _SQPCHEADER_H_
+#define _SQPCHEADER_H_
+
+#if defined(_MSC_VER) && defined(_DEBUG)
+#include <crtdbg.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <new>
+//squirrel stuff
+#include <squirrel.h>
+#include "sqobject.h"
+#include "sqstate.h"
+
+#endif //_SQPCHEADER_H_
--- /dev/null
+/*
+ see copyright notice in squirrel.h
+*/
+#include "sqpcheader.h"
+#include "sqopcodes.h"
+#include "sqvm.h"
+#include "sqfuncproto.h"
+#include "sqclosure.h"
+#include "sqstring.h"
+#include "sqtable.h"
+#include "sqarray.h"
+#include "squserdata.h"
+#include "sqclass.h"
+
+SQObjectPtr _null_;
+SQObjectPtr _true_(true);
+SQObjectPtr _false_(false);
+SQObjectPtr _one_((SQInteger)1);
+SQObjectPtr _minusone_((SQInteger)-1);
+
+SQSharedState::SQSharedState()
+{
+ _compilererrorhandler = NULL;
+ _printfunc = NULL;
+ _debuginfo = false;
+ _notifyallexceptions = false;
+}
+
+#define newsysstring(s) { \
+ _systemstrings->push_back(SQString::Create(this,s)); \
+ }
+
+#define newmetamethod(s) { \
+ _metamethods->push_back(SQString::Create(this,s)); \
+ _table(_metamethodsmap)->NewSlot(_metamethods->back(),(SQInteger)(_metamethods->size()-1)); \
+ }
+
+bool CompileTypemask(SQIntVec &res,const SQChar *typemask)
+{
+ SQInteger i = 0;
+
+ SQInteger mask = 0;
+ while(typemask[i] != 0) {
+
+ switch(typemask[i]){
+ case 'o': mask |= _RT_NULL; break;
+ case 'i': mask |= _RT_INTEGER; break;
+ case 'f': mask |= _RT_FLOAT; break;
+ case 'n': mask |= (_RT_FLOAT | _RT_INTEGER); break;
+ case 's': mask |= _RT_STRING; break;
+ case 't': mask |= _RT_TABLE; break;
+ case 'a': mask |= _RT_ARRAY; break;
+ case 'u': mask |= _RT_USERDATA; break;
+ case 'c': mask |= (_RT_CLOSURE | _RT_NATIVECLOSURE); break;
+ case 'b': mask |= _RT_BOOL; break;
+ case 'g': mask |= _RT_GENERATOR; break;
+ case 'p': mask |= _RT_USERPOINTER; break;
+ case 'v': mask |= _RT_THREAD; break;
+ case 'x': mask |= _RT_INSTANCE; break;
+ case 'y': mask |= _RT_CLASS; break;
+ case 'r': mask |= _RT_WEAKREF; break;
+ case '.': mask = -1; res.push_back(mask); i++; mask = 0; continue;
+ case ' ': i++; continue; //ignores spaces
+ default:
+ return false;
+ }
+ i++;
+ if(typemask[i] == '|') {
+ i++;
+ if(typemask[i] == 0)
+ return false;
+ continue;
+ }
+ res.push_back(mask);
+ mask = 0;
+
+ }
+ return true;
+}
+
+SQTable *CreateDefaultDelegate(SQSharedState *ss,SQRegFunction *funcz)
+{
+ SQInteger i=0;
+ SQTable *t=SQTable::Create(ss,0);
+ while(funcz[i].name!=0){
+ SQNativeClosure *nc = SQNativeClosure::Create(ss,funcz[i].f);
+ nc->_nparamscheck = funcz[i].nparamscheck;
+ nc->_name = SQString::Create(ss,funcz[i].name);
+ if(funcz[i].typemask && !CompileTypemask(nc->_typecheck,funcz[i].typemask))
+ return NULL;
+ t->NewSlot(SQString::Create(ss,funcz[i].name),nc);
+ i++;
+ }
+ return t;
+}
+
+void SQSharedState::Init()
+{
+ _scratchpad=NULL;
+ _scratchpadsize=0;
+#ifndef NO_GARBAGE_COLLECTOR
+ _gc_chain=NULL;
+#endif
+ sq_new(_stringtable,StringTable);
+ sq_new(_metamethods,SQObjectPtrVec);
+ sq_new(_systemstrings,SQObjectPtrVec);
+ sq_new(_types,SQObjectPtrVec);
+ _metamethodsmap = SQTable::Create(this,MT_LAST-1);
+ //adding type strings to avoid memory trashing
+ //types names
+ newsysstring(_SC("null"));
+ newsysstring(_SC("table"));
+ newsysstring(_SC("array"));
+ newsysstring(_SC("closure"));
+ newsysstring(_SC("string"));
+ newsysstring(_SC("userdata"));
+ newsysstring(_SC("integer"));
+ newsysstring(_SC("float"));
+ newsysstring(_SC("userpointer"));
+ newsysstring(_SC("function"));
+ newsysstring(_SC("generator"));
+ newsysstring(_SC("thread"));
+ newsysstring(_SC("class"));
+ newsysstring(_SC("instance"));
+ newsysstring(_SC("bool"));
+ //meta methods
+ newmetamethod(MM_ADD);
+ newmetamethod(MM_SUB);
+ newmetamethod(MM_MUL);
+ newmetamethod(MM_DIV);
+ newmetamethod(MM_UNM);
+ newmetamethod(MM_MODULO);
+ newmetamethod(MM_SET);
+ newmetamethod(MM_GET);
+ newmetamethod(MM_TYPEOF);
+ newmetamethod(MM_NEXTI);
+ newmetamethod(MM_CMP);
+ newmetamethod(MM_CALL);
+ newmetamethod(MM_CLONED);
+ newmetamethod(MM_NEWSLOT);
+ newmetamethod(MM_DELSLOT);
+ newmetamethod(MM_TOSTRING);
+ newmetamethod(MM_NEWMEMBER);
+ newmetamethod(MM_INHERITED);
+
+ _constructoridx = SQString::Create(this,_SC("constructor"));
+ _registry = SQTable::Create(this,0);
+ _consts = SQTable::Create(this,0);
+ _table_default_delegate = CreateDefaultDelegate(this,_table_default_delegate_funcz);
+ _array_default_delegate = CreateDefaultDelegate(this,_array_default_delegate_funcz);
+ _string_default_delegate = CreateDefaultDelegate(this,_string_default_delegate_funcz);
+ _number_default_delegate = CreateDefaultDelegate(this,_number_default_delegate_funcz);
+ _closure_default_delegate = CreateDefaultDelegate(this,_closure_default_delegate_funcz);
+ _generator_default_delegate = CreateDefaultDelegate(this,_generator_default_delegate_funcz);
+ _thread_default_delegate = CreateDefaultDelegate(this,_thread_default_delegate_funcz);
+ _class_default_delegate = CreateDefaultDelegate(this,_class_default_delegate_funcz);
+ _instance_default_delegate = CreateDefaultDelegate(this,_instance_default_delegate_funcz);
+ _weakref_default_delegate = CreateDefaultDelegate(this,_weakref_default_delegate_funcz);
+
+}
+
+SQSharedState::~SQSharedState()
+{
+ _constructoridx = _null_;
+ _table(_registry)->Finalize();
+ _table(_consts)->Finalize();
+ _table(_metamethodsmap)->Finalize();
+ _registry = _null_;
+ _consts = _null_;
+ _metamethodsmap = _null_;
+ while(!_systemstrings->empty()) {
+ _systemstrings->back()=_null_;
+ _systemstrings->pop_back();
+ }
+ _thread(_root_vm)->Finalize();
+ _root_vm = _null_;
+ _table_default_delegate = _null_;
+ _array_default_delegate = _null_;
+ _string_default_delegate = _null_;
+ _number_default_delegate = _null_;
+ _closure_default_delegate = _null_;
+ _generator_default_delegate = _null_;
+ _thread_default_delegate = _null_;
+ _class_default_delegate = _null_;
+ _instance_default_delegate = _null_;
+ _weakref_default_delegate = _null_;
+ _refs_table.Finalize();
+#ifndef NO_GARBAGE_COLLECTOR
+ SQCollectable *t = _gc_chain;
+ SQCollectable *nx = NULL;
+ while(t) {
+ t->_uiRef++;
+ t->Finalize();
+ nx = t->_next;
+ if(--t->_uiRef == 0)
+ t->Release();
+ t=nx;
+ }
+ assert(_gc_chain==NULL); //just to proove a theory
+ while(_gc_chain){
+ _gc_chain->_uiRef++;
+ _gc_chain->Release();
+ }
+#endif
+
+ sq_delete(_types,SQObjectPtrVec);
+ sq_delete(_systemstrings,SQObjectPtrVec);
+ sq_delete(_metamethods,SQObjectPtrVec);
+ sq_delete(_stringtable,StringTable);
+ if(_scratchpad)SQ_FREE(_scratchpad,_scratchpadsize);
+}
+
+
+SQInteger SQSharedState::GetMetaMethodIdxByName(const SQObjectPtr &name)
+{
+ if(type(name) != OT_STRING)
+ return -1;
+ SQObjectPtr ret;
+ if(_table(_metamethodsmap)->Get(name,ret)) {
+ return _integer(ret);
+ }
+ return -1;
+}
+
+#ifndef NO_GARBAGE_COLLECTOR
+
+void SQSharedState::MarkObject(SQObjectPtr &o,SQCollectable **chain)
+{
+ switch(type(o)){
+ case OT_TABLE:_table(o)->Mark(chain);break;
+ case OT_ARRAY:_array(o)->Mark(chain);break;
+ case OT_USERDATA:_userdata(o)->Mark(chain);break;
+ case OT_CLOSURE:_closure(o)->Mark(chain);break;
+ case OT_NATIVECLOSURE:_nativeclosure(o)->Mark(chain);break;
+ case OT_GENERATOR:_generator(o)->Mark(chain);break;
+ case OT_THREAD:_thread(o)->Mark(chain);break;
+ case OT_CLASS:_class(o)->Mark(chain);break;
+ case OT_INSTANCE:_instance(o)->Mark(chain);break;
+ default: break; //shutup compiler
+ }
+}
+
+
+SQInteger SQSharedState::CollectGarbage(SQVM *vm)
+{
+ SQInteger n=0;
+ SQCollectable *tchain=NULL;
+ SQVM *vms = _thread(_root_vm);
+
+ vms->Mark(&tchain);
+ SQInteger x = _table(_thread(_root_vm)->_roottable)->CountUsed();
+ _refs_table.Mark(&tchain);
+ MarkObject(_registry,&tchain);
+ MarkObject(_consts,&tchain);
+ MarkObject(_metamethodsmap,&tchain);
+ MarkObject(_table_default_delegate,&tchain);
+ MarkObject(_array_default_delegate,&tchain);
+ MarkObject(_string_default_delegate,&tchain);
+ MarkObject(_number_default_delegate,&tchain);
+ MarkObject(_generator_default_delegate,&tchain);
+ MarkObject(_thread_default_delegate,&tchain);
+ MarkObject(_closure_default_delegate,&tchain);
+ MarkObject(_class_default_delegate,&tchain);
+ MarkObject(_instance_default_delegate,&tchain);
+ MarkObject(_weakref_default_delegate,&tchain);
+
+ SQCollectable *t = _gc_chain;
+ SQCollectable *nx = NULL;
+ while(t) {
+ t->_uiRef++;
+ t->Finalize();
+ nx = t->_next;
+ if(--t->_uiRef == 0)
+ t->Release();
+ t = nx;
+ n++;
+ }
+
+ t = tchain;
+ while(t) {
+ t->UnMark();
+ t = t->_next;
+ }
+ _gc_chain = tchain;
+ SQInteger z = _table(_thread(_root_vm)->_roottable)->CountUsed();
+ assert(z == x);
+ return n;
+}
+#endif
+
+#ifndef NO_GARBAGE_COLLECTOR
+void SQCollectable::AddToChain(SQCollectable **chain,SQCollectable *c)
+{
+ c->_prev = NULL;
+ c->_next = *chain;
+ if(*chain) (*chain)->_prev = c;
+ *chain = c;
+}
+
+void SQCollectable::RemoveFromChain(SQCollectable **chain,SQCollectable *c)
+{
+ if(c->_prev) c->_prev->_next = c->_next;
+ else *chain = c->_next;
+ if(c->_next)
+ c->_next->_prev = c->_prev;
+ c->_next = NULL;
+ c->_prev = NULL;
+}
+#endif
+
+SQChar* SQSharedState::GetScratchPad(SQInteger size)
+{
+ SQInteger newsize;
+ if(size>0) {
+ if(_scratchpadsize < size) {
+ newsize = size + (size>>1);
+ _scratchpad = (SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize);
+ _scratchpadsize = newsize;
+
+ }else if(_scratchpadsize >= (size<<5)) {
+ newsize = _scratchpadsize >> 1;
+ _scratchpad = (SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize);
+ _scratchpadsize = newsize;
+ }
+ }
+ return _scratchpad;
+}
+
+RefTable::RefTable()
+{
+ AllocNodes(4);
+}
+
+void RefTable::Finalize()
+{
+ RefNode *nodes = _nodes;
+ for(SQUnsignedInteger n = 0; n < _numofslots; n++) {
+ nodes->obj = _null_;
+ nodes++;
+ }
+}
+
+RefTable::~RefTable()
+{
+ SQ_FREE(_buckets,(_numofslots * sizeof(RefNode *)) + (_numofslots * sizeof(RefNode)));
+}
+
+#ifndef NO_GARBAGE_COLLECTOR
+void RefTable::Mark(SQCollectable **chain)
+{
+ RefNode *nodes = (RefNode *)_nodes;
+ for(SQUnsignedInteger n = 0; n < _numofslots; n++) {
+ if(type(nodes->obj) != OT_NULL) {
+ SQSharedState::MarkObject(nodes->obj,chain);
+ }
+ nodes++;
+ }
+}
+#endif
+
+void RefTable::AddRef(SQObject &obj)
+{
+ SQHash mainpos;
+ RefNode *prev;
+ RefNode *ref = Get(obj,mainpos,&prev,true);
+ ref->refs++;
+}
+
+SQBool RefTable::Release(SQObject &obj)
+{
+ SQHash mainpos;
+ RefNode *prev;
+ RefNode *ref = Get(obj,mainpos,&prev,false);
+ if(ref) {
+ if(--ref->refs == 0) {
+ SQObjectPtr o = ref->obj;
+ if(prev) {
+ prev->next = ref->next;
+ }
+ else {
+ _buckets[mainpos] = ref->next;
+ }
+ ref->next = _freelist;
+ _freelist = ref;
+ _slotused--;
+ ref->obj = _null_;
+ //<<FIXME>>test for shrink?
+ return SQTrue;
+ }
+ }
+ else {
+ assert(0);
+ }
+ return SQFalse;
+}
+
+void RefTable::Resize(SQUnsignedInteger size)
+{
+ RefNode **oldbucks = _buckets;
+ RefNode *t = _nodes;
+ SQUnsignedInteger oldnumofslots = _numofslots;
+ AllocNodes(size);
+ //rehash
+ SQUnsignedInteger nfound = 0;
+ for(SQUnsignedInteger n = 0; n < oldnumofslots; n++) {
+ if(type(t->obj) != OT_NULL) {
+ //add back;
+ assert(t->refs != 0);
+ RefNode *nn = Add(::HashObj(t->obj)&(_numofslots-1),t->obj);
+ nn->refs = t->refs;
+ t->obj = _null_;
+ nfound++;
+ }
+ t++;
+ }
+ assert(nfound == oldnumofslots);
+ SQ_FREE(oldbucks,(oldnumofslots * sizeof(RefNode *)) + (oldnumofslots * sizeof(RefNode)));
+}
+
+RefTable::RefNode *RefTable::Add(SQHash mainpos,SQObject &obj)
+{
+ RefNode *t = _buckets[mainpos];
+ RefNode *newnode = _freelist;
+ newnode->obj = obj;
+ _buckets[mainpos] = newnode;
+ _freelist = _freelist->next;
+ newnode->next = t;
+ assert(newnode->refs == 0);
+ _slotused++;
+ return newnode;
+}
+
+RefTable::RefNode *RefTable::Get(SQObject &obj,SQHash &mainpos,RefNode **prev,bool add)
+{
+ RefNode *ref;
+ mainpos = ::HashObj(obj)&(_numofslots-1);
+ *prev = NULL;
+ for (ref = _buckets[mainpos]; ref; ) {
+ if(_rawval(ref->obj) == _rawval(obj) && type(ref->obj) == type(obj))
+ break;
+ *prev = ref;
+ ref = ref->next;
+ }
+ if(ref == NULL && add) {
+ if(_numofslots == _slotused) {
+ assert(_freelist == 0);
+ Resize(_numofslots*2);
+ mainpos = ::HashObj(obj)&(_numofslots-1);
+ }
+ ref = Add(mainpos,obj);
+ }
+ return ref;
+}
+
+void RefTable::AllocNodes(SQUnsignedInteger size)
+{
+ RefNode **bucks;
+ RefNode *nodes;
+ bucks = (RefNode **)SQ_MALLOC((size * sizeof(RefNode *)) + (size * sizeof(RefNode)));
+ nodes = (RefNode *)&bucks[size];
+ RefNode *temp = nodes;
+ SQUnsignedInteger n;
+ for(n = 0; n < size - 1; n++) {
+ bucks[n] = NULL;
+ temp->refs = 0;
+ new (&temp->obj) SQObjectPtr;
+ temp->next = temp+1;
+ temp++;
+ }
+ bucks[n] = NULL;
+ temp->refs = 0;
+ new (&temp->obj) SQObjectPtr;
+ temp->next = NULL;
+ _freelist = nodes;
+ _nodes = nodes;
+ _buckets = bucks;
+ _slotused = 0;
+ _numofslots = size;
+}
+//////////////////////////////////////////////////////////////////////////
+//StringTable
+/*
+* The following code is based on Lua 4.0 (Copyright 1994-2002 Tecgraf, PUC-Rio.)
+* http://www.lua.org/copyright.html#4
+* http://www.lua.org/source/4.0.1/src_lstring.c.html
+*/
+
+StringTable::StringTable()
+{
+ AllocNodes(4);
+ _slotused = 0;
+}
+
+StringTable::~StringTable()
+{
+ SQ_FREE(_strings,sizeof(SQString*)*_numofslots);
+ _strings = NULL;
+}
+
+void StringTable::AllocNodes(SQInteger size)
+{
+ _numofslots = size;
+ _strings = (SQString**)SQ_MALLOC(sizeof(SQString*)*_numofslots);
+ memset(_strings,0,sizeof(SQString*)*_numofslots);
+}
+
+SQString *StringTable::Add(const SQChar *news,SQInteger len)
+{
+ if(len<0)
+ len = (SQInteger)scstrlen(news);
+ SQHash h = ::_hashstr(news,len)&(_numofslots-1);
+ SQString *s;
+ for (s = _strings[h]; s; s = s->_next){
+ if(s->_len == len && (!memcmp(news,s->_val,rsl(len))))
+ return s; //found
+ }
+
+ SQString *t=(SQString *)SQ_MALLOC(rsl(len)+sizeof(SQString));
+ new (t) SQString;
+ memcpy(t->_val,news,rsl(len));
+ t->_val[len] = _SC('\0');
+ t->_len = len;
+ t->_hash = ::_hashstr(news,len);
+ t->_next = _strings[h];
+ _strings[h] = t;
+ _slotused++;
+ if (_slotused > _numofslots) /* too crowded? */
+ Resize(_numofslots*2);
+ return t;
+}
+
+void StringTable::Resize(SQInteger size)
+{
+ SQInteger oldsize=_numofslots;
+ SQString **oldtable=_strings;
+ AllocNodes(size);
+ for (SQInteger i=0; i<oldsize; i++){
+ SQString *p = oldtable[i];
+ while(p){
+ SQString *next = p->_next;
+ SQHash h = p->_hash&(_numofslots-1);
+ p->_next = _strings[h];
+ _strings[h] = p;
+ p = next;
+ }
+ }
+ SQ_FREE(oldtable,oldsize*sizeof(SQString*));
+}
+
+void StringTable::Remove(SQString *bs)
+{
+ SQString *s;
+ SQString *prev=NULL;
+ SQHash h = bs->_hash&(_numofslots - 1);
+
+ for (s = _strings[h]; s; ){
+ if(s == bs){
+ if(prev)
+ prev->_next = s->_next;
+ else
+ _strings[h] = s->_next;
+ _slotused--;
+ SQInteger slen = s->_len;
+ s->~SQString();
+ SQ_FREE(s,sizeof(SQString) + rsl(slen));
+ return;
+ }
+ prev = s;
+ s = s->_next;
+ }
+ assert(0);//if this fail something is wrong
+}
--- /dev/null
+/* see copyright notice in squirrel.h */
+#ifndef _SQSTATE_H_
+#define _SQSTATE_H_
+
+#include "squtils.h"
+#include "sqobject.h"
+struct SQString;
+struct SQTable;
+//max number of character for a printed number
+#define NUMBER_MAX_CHAR 50
+
+struct StringTable
+{
+ StringTable();
+ ~StringTable();
+ SQString *Add(const SQChar *,SQInteger len);
+ void Remove(SQString *);
+private:
+ void Resize(SQInteger size);
+ void AllocNodes(SQInteger size);
+ SQString **_strings;
+ SQUnsignedInteger _numofslots;
+ SQUnsignedInteger _slotused;
+};
+
+struct RefTable {
+ struct RefNode {
+ SQObjectPtr obj;
+ SQUnsignedInteger refs;
+ struct RefNode *next;
+ };
+ RefTable();
+ ~RefTable();
+ void AddRef(SQObject &obj);
+ SQBool Release(SQObject &obj);
+#ifndef NO_GARBAGE_COLLECTOR
+ void Mark(SQCollectable **chain);
+#endif
+ void Finalize();
+private:
+ RefNode *Get(SQObject &obj,SQHash &mainpos,RefNode **prev,bool add);
+ RefNode *Add(SQHash mainpos,SQObject &obj);
+ void Resize(SQUnsignedInteger size);
+ void AllocNodes(SQUnsignedInteger size);
+ SQUnsignedInteger _numofslots;
+ SQUnsignedInteger _slotused;
+ RefNode *_nodes;
+ RefNode *_freelist;
+ RefNode **_buckets;
+};
+
+#define ADD_STRING(ss,str,len) ss->_stringtable->Add(str,len)
+#define REMOVE_STRING(ss,bstr) ss->_stringtable->Remove(bstr)
+
+struct SQObjectPtr;
+
+struct SQSharedState
+{
+ SQSharedState();
+ ~SQSharedState();
+ void Init();
+public:
+ SQChar* GetScratchPad(SQInteger size);
+ SQInteger GetMetaMethodIdxByName(const SQObjectPtr &name);
+#ifndef NO_GARBAGE_COLLECTOR
+ SQInteger CollectGarbage(SQVM *vm);
+ static void MarkObject(SQObjectPtr &o,SQCollectable **chain);
+#endif
+ SQObjectPtrVec *_metamethods;
+ SQObjectPtr _metamethodsmap;
+ SQObjectPtrVec *_systemstrings;
+ SQObjectPtrVec *_types;
+ StringTable *_stringtable;
+ RefTable _refs_table;
+ SQObjectPtr _registry;
+ SQObjectPtr _consts;
+ SQObjectPtr _constructoridx;
+#ifndef NO_GARBAGE_COLLECTOR
+ SQCollectable *_gc_chain;
+#endif
+ SQObjectPtr _root_vm;
+ SQObjectPtr _table_default_delegate;
+ static SQRegFunction _table_default_delegate_funcz[];
+ SQObjectPtr _array_default_delegate;
+ static SQRegFunction _array_default_delegate_funcz[];
+ SQObjectPtr _string_default_delegate;
+ static SQRegFunction _string_default_delegate_funcz[];
+ SQObjectPtr _number_default_delegate;
+ static SQRegFunction _number_default_delegate_funcz[];
+ SQObjectPtr _generator_default_delegate;
+ static SQRegFunction _generator_default_delegate_funcz[];
+ SQObjectPtr _closure_default_delegate;
+ static SQRegFunction _closure_default_delegate_funcz[];
+ SQObjectPtr _thread_default_delegate;
+ static SQRegFunction _thread_default_delegate_funcz[];
+ SQObjectPtr _class_default_delegate;
+ static SQRegFunction _class_default_delegate_funcz[];
+ SQObjectPtr _instance_default_delegate;
+ static SQRegFunction _instance_default_delegate_funcz[];
+ SQObjectPtr _weakref_default_delegate;
+ static SQRegFunction _weakref_default_delegate_funcz[];
+
+ SQCOMPILERERROR _compilererrorhandler;
+ SQPRINTFUNCTION _printfunc;
+ bool _debuginfo;
+ bool _notifyallexceptions;
+private:
+ SQChar *_scratchpad;
+ SQInteger _scratchpadsize;
+};
+
+#define _sp(s) (_sharedstate->GetScratchPad(s))
+#define _spval (_sharedstate->GetScratchPad(-1))
+
+#define _table_ddel _table(_sharedstate->_table_default_delegate)
+#define _array_ddel _table(_sharedstate->_array_default_delegate)
+#define _string_ddel _table(_sharedstate->_string_default_delegate)
+#define _number_ddel _table(_sharedstate->_number_default_delegate)
+#define _generator_ddel _table(_sharedstate->_generator_default_delegate)
+#define _closure_ddel _table(_sharedstate->_closure_default_delegate)
+#define _thread_ddel _table(_sharedstate->_thread_default_delegate)
+#define _class_ddel _table(_sharedstate->_class_default_delegate)
+#define _instance_ddel _table(_sharedstate->_instance_default_delegate)
+#define _weakref_ddel _table(_sharedstate->_weakref_default_delegate)
+
+#ifdef SQUNICODE //rsl REAL STRING LEN
+#define rsl(l) ((l)<<1)
+#else
+#define rsl(l) (l)
+#endif
+
+extern SQObjectPtr _null_;
+extern SQObjectPtr _true_;
+extern SQObjectPtr _false_;
+extern SQObjectPtr _one_;
+extern SQObjectPtr _minusone_;
+
+bool CompileTypemask(SQIntVec &res,const SQChar *typemask);
+
+void *sq_vm_malloc(SQUnsignedInteger size);
+void *sq_vm_realloc(void *p,SQUnsignedInteger oldsize,SQUnsignedInteger size);
+void sq_vm_free(void *p,SQUnsignedInteger size);
+#endif //_SQSTATE_H_
--- /dev/null
+/* see copyright notice in squirrel.h */
+#ifndef _SQSTRING_H_
+#define _SQSTRING_H_
+
+inline SQHash _hashstr (const SQChar *s, size_t l)
+{
+ SQHash h = (SQHash)l; /* seed */
+ size_t step = (l>>5)|1; /* if string is too long, don't hash all its chars */
+ for (; l>=step; l-=step)
+ h = h ^ ((h<<5)+(h>>2)+(unsigned short)*(s++));
+ return h;
+}
+
+struct SQString : public SQRefCounted
+{
+ SQString(){}
+ ~SQString(){}
+public:
+ static SQString *Create(SQSharedState *ss, const SQChar *, SQInteger len = -1 );
+ SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);
+ void Release();
+ SQSharedState *_sharedstate;
+ SQString *_next; //chain for the string table
+ SQInteger _len;
+ SQHash _hash;
+ SQChar _val[1];
+};
+
+
+
+#endif //_SQSTRING_H_
--- /dev/null
+/*
+see copyright notice in squirrel.h
+*/
+#include "sqpcheader.h"
+#include "sqvm.h"
+#include "sqtable.h"
+#include "sqfuncproto.h"
+#include "sqclosure.h"
+
+SQTable::SQTable(SQSharedState *ss,SQInteger nInitialSize)
+{
+ SQInteger pow2size=MINPOWER2;
+ while(nInitialSize>pow2size)pow2size=pow2size<<1;
+ AllocNodes(pow2size);
+ _usednodes = 0;
+ _delegate = NULL;
+ INIT_CHAIN();
+ ADD_TO_CHAIN(&_sharedstate->_gc_chain,this);
+}
+
+void SQTable::Remove(const SQObjectPtr &key)
+{
+
+ _HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1));
+ if (n) {
+ n->val = n->key = _null_;
+ _usednodes--;
+ Rehash(false);
+ }
+}
+
+void SQTable::AllocNodes(SQInteger nSize)
+{
+ _HashNode *nodes=(_HashNode *)SQ_MALLOC(sizeof(_HashNode)*nSize);
+ for(SQInteger i=0;i<nSize;i++){
+ new (&nodes[i]) _HashNode;
+ nodes[i].next=NULL;
+ }
+ _numofnodes=nSize;
+ _nodes=nodes;
+ _firstfree=&_nodes[_numofnodes-1];
+}
+
+void SQTable::Rehash(bool force)
+{
+ SQInteger oldsize=_numofnodes;
+ //prevent problems with the integer division
+ if(oldsize<4)oldsize=4;
+ _HashNode *nold=_nodes;
+ SQInteger nelems=CountUsed();
+ if (nelems >= oldsize-oldsize/4) /* using more than 3/4? */
+ AllocNodes(oldsize*2);
+ else if (nelems <= oldsize/4 && /* less than 1/4? */
+ oldsize > MINPOWER2)
+ AllocNodes(oldsize/2);
+ else if(force)
+ AllocNodes(oldsize);
+ else
+ return;
+ _usednodes = 0;
+ for (SQInteger i=0; i<oldsize; i++) {
+ _HashNode *old = nold+i;
+ if (type(old->key) != OT_NULL)
+ NewSlot(old->key,old->val);
+ }
+ for(SQInteger k=0;k<oldsize;k++)
+ nold[k].~_HashNode();
+ SQ_FREE(nold,oldsize*sizeof(_HashNode));
+}
+
+SQTable *SQTable::Clone()
+{
+ SQTable *nt=Create(_opt_ss(this),_numofnodes);
+ SQInteger ridx=0;
+ SQObjectPtr key,val;
+ while((ridx=Next(true,ridx,key,val))!=-1){
+ nt->NewSlot(key,val);
+ }
+ nt->SetDelegate(_delegate);
+ return nt;
+}
+
+bool SQTable::Get(const SQObjectPtr &key,SQObjectPtr &val)
+{
+ if(type(key) == OT_NULL)
+ return false;
+ _HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1));
+ if (n) {
+ val = _realval(n->val);
+ return true;
+ }
+ return false;
+}
+bool SQTable::NewSlot(const SQObjectPtr &key,const SQObjectPtr &val)
+{
+ assert(type(key) != OT_NULL);
+ SQHash h = HashObj(key) & (_numofnodes - 1);
+ _HashNode *n = _Get(key, h);
+ if (n) {
+ n->val = val;
+ return false;
+ }
+ _HashNode *mp = &_nodes[h];
+ n = mp;
+
+
+ //key not found I'll insert it
+ //main pos is not free
+
+ if(type(mp->key) != OT_NULL) {
+ n = _firstfree; /* get a free place */
+ SQHash mph = HashObj(mp->key) & (_numofnodes - 1);
+ _HashNode *othern; /* main position of colliding node */
+
+ if (mp > n && (othern = &_nodes[mph]) != mp){
+ /* yes; move colliding node into free position */
+ while (othern->next != mp){
+ assert(othern->next != NULL);
+ othern = othern->next; /* find previous */
+ }
+ othern->next = n; /* redo the chain with `n' in place of `mp' */
+ n->key = mp->key;
+ n->val = mp->val;/* copy colliding node into free pos. (mp->next also goes) */
+ n->next = mp->next;
+ mp->key = _null_;
+ mp->val = _null_;
+ mp->next = NULL; /* now `mp' is free */
+ }
+ else{
+ /* new node will go into free position */
+ n->next = mp->next; /* chain new position */
+ mp->next = n;
+ mp = n;
+ }
+ }
+ mp->key = key;
+
+ for (;;) { /* correct `firstfree' */
+ if (type(_firstfree->key) == OT_NULL && _firstfree->next == NULL) {
+ mp->val = val;
+ _usednodes++;
+ return true; /* OK; table still has a free place */
+ }
+ else if (_firstfree == _nodes) break; /* cannot decrement from here */
+ else (_firstfree)--;
+ }
+ Rehash(true);
+ return NewSlot(key, val);
+}
+
+SQInteger SQTable::Next(bool getweakrefs,const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval)
+{
+ SQInteger idx = (SQInteger)TranslateIndex(refpos);
+ while (idx < _numofnodes) {
+ if(type(_nodes[idx].key) != OT_NULL) {
+ //first found
+ _HashNode &n = _nodes[idx];
+ outkey = n.key;
+ outval = getweakrefs?(SQObject)n.val:_realval(n.val);
+ //return idx for the next iteration
+ return ++idx;
+ }
+ ++idx;
+ }
+ //nothing to iterate anymore
+ return -1;
+}
+
+
+bool SQTable::Set(const SQObjectPtr &key, const SQObjectPtr &val)
+{
+ _HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1));
+ if (n) {
+ n->val = val;
+ return true;
+ }
+ return false;
+}
+
+void SQTable::_ClearNodes()
+{
+ for(SQInteger i = 0;i < _numofnodes; i++) { _nodes[i].key = _null_; _nodes[i].val = _null_; }
+}
+
+void SQTable::Finalize()
+{
+ _ClearNodes();
+ SetDelegate(NULL);
+}
+
+void SQTable::Clear()
+{
+ _ClearNodes();
+ _usednodes = 0;
+ Rehash(true);
+}
--- /dev/null
+/* see copyright notice in squirrel.h */
+#ifndef _SQTABLE_H_
+#define _SQTABLE_H_
+/*
+* The following code is based on Lua 4.0 (Copyright 1994-2002 Tecgraf, PUC-Rio.)
+* http://www.lua.org/copyright.html#4
+* http://www.lua.org/source/4.0.1/src_ltable.c.html
+*/
+
+#include "sqstring.h"
+
+
+#define hashptr(p) ((SQHash)(((SQInteger)p) >> 3))
+
+inline SQHash HashObj(const SQObjectPtr &key)
+{
+ switch(type(key)) {
+ case OT_STRING: return _string(key)->_hash;
+ case OT_FLOAT: return (SQHash)((SQInteger)_float(key));
+ case OT_BOOL: case OT_INTEGER: return (SQHash)((SQInteger)_integer(key));
+ default: return hashptr(key._unVal.pRefCounted);
+ }
+}
+
+struct SQTable : public SQDelegable
+{
+private:
+ struct _HashNode
+ {
+ _HashNode() { next = NULL; }
+ SQObjectPtr val;
+ SQObjectPtr key;
+ _HashNode *next;
+ };
+ _HashNode *_firstfree;
+ _HashNode *_nodes;
+ SQInteger _numofnodes;
+ SQInteger _usednodes;
+
+///////////////////////////
+ void AllocNodes(SQInteger nSize);
+ void Rehash(bool force);
+ SQTable(SQSharedState *ss, SQInteger nInitialSize);
+ void _ClearNodes();
+public:
+ static SQTable* Create(SQSharedState *ss,SQInteger nInitialSize)
+ {
+ SQTable *newtable = (SQTable*)SQ_MALLOC(sizeof(SQTable));
+ new (newtable) SQTable(ss, nInitialSize);
+ newtable->_delegate = NULL;
+ return newtable;
+ }
+ void Finalize();
+ SQTable *Clone();
+ ~SQTable()
+ {
+ SetDelegate(NULL);
+ REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
+ for (SQInteger i = 0; i < _numofnodes; i++) _nodes[i].~_HashNode();
+ SQ_FREE(_nodes, _numofnodes * sizeof(_HashNode));
+ }
+#ifndef NO_GARBAGE_COLLECTOR
+ void Mark(SQCollectable **chain);
+#endif
+ inline _HashNode *_Get(const SQObjectPtr &key,SQHash hash)
+ {
+ _HashNode *n = &_nodes[hash];
+ do{
+ if(_rawval(n->key) == _rawval(key) && type(n->key) == type(key)){
+ return n;
+ }
+ }while((n = n->next));
+ return NULL;
+ }
+ bool Get(const SQObjectPtr &key,SQObjectPtr &val);
+ void Remove(const SQObjectPtr &key);
+ bool Set(const SQObjectPtr &key, const SQObjectPtr &val);
+ //returns true if a new slot has been created false if it was already present
+ bool NewSlot(const SQObjectPtr &key,const SQObjectPtr &val);
+ SQInteger Next(bool getweakrefs,const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);
+
+ SQInteger CountUsed(){ return _usednodes;}
+ void Clear();
+ void Release()
+ {
+ sq_delete(this, SQTable);
+ }
+
+};
+
+#endif //_SQTABLE_H_
--- /dev/null
+/* see copyright notice in squirrel.h */
+#ifndef _SQUSERDATA_H_
+#define _SQUSERDATA_H_
+
+struct SQUserData : SQDelegable
+{
+ SQUserData(SQSharedState *ss){ _delegate = 0; _hook = NULL; INIT_CHAIN(); ADD_TO_CHAIN(&_ss(this)->_gc_chain, this); }
+ ~SQUserData()
+ {
+ REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain, this);
+ SetDelegate(NULL);
+ }
+ static SQUserData* Create(SQSharedState *ss, SQInteger size)
+ {
+ SQUserData* ud = (SQUserData*)SQ_MALLOC(sizeof(SQUserData)+(size-1));
+ new (ud) SQUserData(ss);
+ ud->_size = size;
+ ud->_typetag = 0;
+ return ud;
+ }
+#ifndef NO_GARBAGE_COLLECTOR
+ void Mark(SQCollectable **chain);
+ void Finalize(){SetDelegate(NULL);}
+#endif
+ void Release() {
+ if (_hook) _hook(_val,_size);
+ SQInteger tsize = _size - 1;
+ this->~SQUserData();
+ SQ_FREE(this, sizeof(SQUserData) + tsize);
+ }
+
+ SQInteger _size;
+ SQRELEASEHOOK _hook;
+ SQUserPointer _typetag;
+ SQChar _val[1];
+};
+
+#endif //_SQUSERDATA_H_
--- /dev/null
+/* see copyright notice in squirrel.h */
+#ifndef _SQUTILS_H_
+#define _SQUTILS_H_
+
+#define sq_new(__ptr,__type) {__ptr=(__type *)sq_vm_malloc(sizeof(__type));new (__ptr) __type;}
+#define sq_delete(__ptr,__type) {__ptr->~__type();sq_vm_free(__ptr,sizeof(__type));}
+#define SQ_MALLOC(__size) sq_vm_malloc((__size));
+#define SQ_FREE(__ptr,__size) sq_vm_free((__ptr),(__size));
+#define SQ_REALLOC(__ptr,__oldsize,__size) sq_vm_realloc((__ptr),(__oldsize),(__size));
+
+//sqvector mini vector class, supports objects by value
+template<typename T> class sqvector
+{
+public:
+ sqvector()
+ {
+ _vals = NULL;
+ _size = 0;
+ _allocated = 0;
+ }
+ sqvector(const sqvector<T>& v)
+ {
+ copy(v);
+ }
+ void copy(const sqvector<T>& v)
+ {
+ resize(v._size);
+ for(SQUnsignedInteger i = 0; i < v._size; i++) {
+ new ((void *)&_vals[i]) T(v._vals[i]);
+ }
+ _size = v._size;
+ }
+ ~sqvector()
+ {
+ if(_allocated) {
+ for(SQUnsignedInteger i = 0; i < _size; i++)
+ _vals[i].~T();
+ SQ_FREE(_vals, (_allocated * sizeof(T)));
+ }
+ }
+ void reserve(SQUnsignedInteger newsize) { _realloc(newsize); }
+ void resize(SQUnsignedInteger newsize, const T& fill = T())
+ {
+ if(newsize > _allocated)
+ _realloc(newsize);
+ if(newsize > _size) {
+ while(_size < newsize) {
+ new ((void *)&_vals[_size]) T(fill);
+ _size++;
+ }
+ }
+ else{
+ for(SQUnsignedInteger i = newsize; i < _size; i++) {
+ _vals[i].~T();
+ }
+ _size = newsize;
+ }
+ }
+ void shrinktofit() { if(_size > 4) { _realloc(_size); } }
+ T& top() const { return _vals[_size - 1]; }
+ inline SQUnsignedInteger size() const { return _size; }
+ bool empty() const { return (_size <= 0); }
+ inline T &push_back(const T& val = T())
+ {
+ if(_allocated <= _size)
+ _realloc(_size * 2);
+ return *(new ((void *)&_vals[_size++]) T(val));
+ }
+ inline void pop_back()
+ {
+ _size--; _vals[_size].~T();
+ }
+ void insert(SQUnsignedInteger idx, const T& val)
+ {
+ resize(_size + 1);
+ for(SQUnsignedInteger i = _size - 1; i > idx; i--) {
+ _vals[i] = _vals[i - 1];
+ }
+ _vals[idx] = val;
+ }
+ void remove(SQUnsignedInteger idx)
+ {
+ _vals[idx].~T();
+ if(idx < (_size - 1)) {
+ memmove(&_vals[idx], &_vals[idx+1], sizeof(T) * (_size - idx - 1));
+ }
+ _size--;
+ }
+ SQUnsignedInteger capacity() { return _allocated; }
+ inline T &back() const { return _vals[_size - 1]; }
+ inline T& operator[](SQUnsignedInteger pos) const{ return _vals[pos]; }
+ T* _vals;
+private:
+ void _realloc(SQUnsignedInteger newsize)
+ {
+ newsize = (newsize > 0)?newsize:4;
+ _vals = (T*)SQ_REALLOC(_vals, _allocated * sizeof(T), newsize * sizeof(T));
+ _allocated = newsize;
+ }
+ SQUnsignedInteger _size;
+ SQUnsignedInteger _allocated;
+};
+
+#endif //_SQUTILS_H_
--- /dev/null
+/*
+ see copyright notice in squirrel.h
+*/
+#include "sqpcheader.h"
+#include <math.h>
+#include <stdlib.h>
+#include "sqopcodes.h"
+#include "sqfuncproto.h"
+#include "sqvm.h"
+#include "sqclosure.h"
+#include "sqstring.h"
+#include "sqtable.h"
+#include "squserdata.h"
+#include "sqarray.h"
+#include "sqclass.h"
+
+#define TOP() (_stack._vals[_top-1])
+
+#define CLEARSTACK(_last_top) { if((_last_top) >= _top) ClearStack(_last_top); }
+void SQVM::ClearStack(SQInteger last_top)
+{
+ SQObjectType tOldType;
+ SQObjectValue unOldVal;
+ while (last_top >= _top) {
+ SQObjectPtr &o = _stack._vals[last_top--];
+ tOldType = o._type;
+ unOldVal = o._unVal;
+ o._type = OT_NULL;
+ o._unVal.pUserPointer = NULL;
+ __Release(tOldType,unOldVal);
+ }
+}
+
+bool SQVM::BW_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2)
+{
+ SQInteger res;
+ SQInteger i1 = _integer(o1), i2 = _integer(o2);
+ if((type(o1)==OT_INTEGER) && (type(o2)==OT_INTEGER))
+ {
+ switch(op) {
+ case BW_AND: res = i1 & i2; break;
+ case BW_OR: res = i1 | i2; break;
+ case BW_XOR: res = i1 ^ i2; break;
+ case BW_SHIFTL: res = i1 << i2; break;
+ case BW_SHIFTR: res = i1 >> i2; break;
+ case BW_USHIFTR:res = (SQInteger)(*((SQUnsignedInteger*)&i1) >> i2); break;
+ default: { Raise_Error(_SC("internal vm error bitwise op failed")); return false; }
+ }
+ }
+ else { Raise_Error(_SC("bitwise op between '%s' and '%s'"),GetTypeName(o1),GetTypeName(o2)); return false;}
+ trg = res;
+ return true;
+}
+
+bool SQVM::ARITH_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2)
+{
+ if(sq_isnumeric(o1) && sq_isnumeric(o2)) {
+ if((type(o1)==OT_INTEGER) && (type(o2)==OT_INTEGER)) {
+ SQInteger res, i1 = _integer(o1), i2 = _integer(o2);
+ switch(op) {
+ case '+': res = i1 + i2; break;
+ case '-': res = i1 - i2; break;
+ case '/': if(i2 == 0) { Raise_Error(_SC("division by zero")); return false; }
+ res = i1 / i2;
+ break;
+ case '*': res = i1 * i2; break;
+ case '%': if(i2 == 0) { Raise_Error(_SC("modulo by zero")); return false; }
+ res = i1 % i2;
+ break;
+ default: res = 0xDEADBEEF;
+ }
+ trg = res;
+ }else{
+ SQFloat res, f1 = tofloat(o1), f2 = tofloat(o2);
+ switch(op) {
+ case '+': res = f1 + f2; break;
+ case '-': res = f1 - f2; break;
+ case '/': res = f1 / f2; break;
+ case '*': res = f1 * f2; break;
+ case '%': res = SQFloat(fmod((double)f1,(double)f2)); break;
+ default: res = 0x0f;
+ }
+ trg = res;
+ }
+ } else {
+ if(op == '+' && (type(o1) == OT_STRING || type(o2) == OT_STRING)){
+ if(!StringCat(o1, o2, trg)) return false;
+ }
+ else if(!ArithMetaMethod(op,o1,o2,trg)) {
+ Raise_Error(_SC("arith op %c on between '%s' and '%s'"),op,GetTypeName(o1),GetTypeName(o2)); return false;
+ }
+ }
+ return true;
+}
+
+SQVM::SQVM(SQSharedState *ss)
+{
+ _sharedstate=ss;
+ _suspended = SQFalse;
+ _suspended_target=-1;
+ _suspended_root = SQFalse;
+ _suspended_traps=-1;
+ _foreignptr=NULL;
+ _nnativecalls=0;
+ _lasterror = _null_;
+ _errorhandler = _null_;
+ _debughook = _null_;
+ ci = NULL;
+ INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);
+}
+
+void SQVM::Finalize()
+{
+ _roottable = _null_;
+ _lasterror = _null_;
+ _errorhandler = _null_;
+ _debughook = _null_;
+ temp_reg = _null_;
+ _callstackdata.resize(0);
+ SQInteger size=_stack.size();
+ for(SQInteger i=0;i<size;i++)
+ _stack[i]=_null_;
+}
+
+SQVM::~SQVM()
+{
+ Finalize();
+ //sq_free(_callsstack,_alloccallsstacksize*sizeof(CallInfo));
+ REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
+}
+
+bool SQVM::ArithMetaMethod(SQInteger op,const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &dest)
+{
+ SQMetaMethod mm;
+ switch(op){
+ case _SC('+'): mm=MT_ADD; break;
+ case _SC('-'): mm=MT_SUB; break;
+ case _SC('/'): mm=MT_DIV; break;
+ case _SC('*'): mm=MT_MUL; break;
+ case _SC('%'): mm=MT_MODULO; break;
+ default: mm = MT_ADD; assert(0); break; //shutup compiler
+ }
+ if(is_delegable(o1) && _delegable(o1)->_delegate) {
+ Push(o1);Push(o2);
+ return CallMetaMethod(_delegable(o1),mm,2,dest);
+ }
+ return false;
+}
+
+bool SQVM::NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o)
+{
+
+ switch(type(o)) {
+ case OT_INTEGER:
+ trg = -_integer(o);
+ return true;
+ case OT_FLOAT:
+ trg = -_float(o);
+ return true;
+ case OT_TABLE:
+ case OT_USERDATA:
+ case OT_INSTANCE:
+ if(_delegable(o)->_delegate) {
+ Push(o);
+ if(CallMetaMethod(_delegable(o), MT_UNM, 1, temp_reg)) {
+ trg = temp_reg;
+ return true;
+ }
+ }
+ default:break; //shutup compiler
+ }
+ Raise_Error(_SC("attempt to negate a %s"), GetTypeName(o));
+ return false;
+}
+
+#define _RET_SUCCEED(exp) { result = (exp); return true; }
+bool SQVM::ObjCmp(const SQObjectPtr &o1,const SQObjectPtr &o2,SQInteger &result)
+{
+ if(type(o1)==type(o2)){
+ if(_userpointer(o1)==_userpointer(o2))_RET_SUCCEED(0);
+ SQObjectPtr res;
+ switch(type(o1)){
+ case OT_STRING:
+ _RET_SUCCEED(scstrcmp(_stringval(o1),_stringval(o2)));
+ case OT_INTEGER:
+ _RET_SUCCEED(_integer(o1)-_integer(o2));
+ case OT_FLOAT:
+ _RET_SUCCEED((_float(o1)<_float(o2))?-1:1);
+ case OT_TABLE:
+ case OT_USERDATA:
+ case OT_INSTANCE:
+ if(_delegable(o1)->_delegate) {
+ Push(o1);Push(o2);
+ if(CallMetaMethod(_delegable(o1),MT_CMP,2,res)) break;
+ }
+ //continues through (no break needed)
+ default:
+ _RET_SUCCEED( _userpointer(o1) < _userpointer(o2)?-1:1 );
+ }
+ if(type(res)!=OT_INTEGER) { Raise_CompareError(o1,o2); return false; }
+ _RET_SUCCEED(_integer(res));
+
+ }
+ else{
+ if(sq_isnumeric(o1) && sq_isnumeric(o2)){
+ if((type(o1)==OT_INTEGER) && (type(o2)==OT_FLOAT)) {
+ if( _integer(o1)==_float(o2) ) { _RET_SUCCEED(0); }
+ else if( _integer(o1)<_float(o2) ) { _RET_SUCCEED(-1); }
+ _RET_SUCCEED(1);
+ }
+ else{
+ if( _float(o1)==_integer(o2) ) { _RET_SUCCEED(0); }
+ else if( _float(o1)<_integer(o2) ) { _RET_SUCCEED(-1); }
+ _RET_SUCCEED(1);
+ }
+ }
+ else if(type(o1)==OT_NULL) {_RET_SUCCEED(-1);}
+ else if(type(o2)==OT_NULL) {_RET_SUCCEED(1);}
+ else { Raise_CompareError(o1,o2); return false; }
+
+ }
+ assert(0);
+ _RET_SUCCEED(0); //cannot happen
+}
+
+bool SQVM::CMP_OP(CmpOP op, const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &res)
+{
+ SQInteger r;
+ if(ObjCmp(o1,o2,r)) {
+ switch(op) {
+ case CMP_G: res = (r > 0)?_true_:_false_; return true;
+ case CMP_GE: res = (r >= 0)?_true_:_false_; return true;
+ case CMP_L: res = (r < 0)?_true_:_false_; return true;
+ case CMP_LE: res = (r <= 0)?_true_:_false_; return true;
+
+ }
+ assert(0);
+ }
+ return false;
+}
+
+void SQVM::ToString(const SQObjectPtr &o,SQObjectPtr &res)
+{
+ switch(type(o)) {
+ case OT_STRING:
+ res = o;
+ return;
+ case OT_FLOAT:
+ scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)),_SC("%g"),_float(o));
+ break;
+ case OT_INTEGER:
+ scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)),_SC("%d"),_integer(o));
+ break;
+ case OT_BOOL:
+ scsprintf(_sp(rsl(6)),_integer(o)?_SC("true"):_SC("false"));
+ break;
+ case OT_TABLE:
+ case OT_USERDATA:
+ case OT_INSTANCE:
+ if(_delegable(o)->_delegate) {
+ Push(o);
+ if(CallMetaMethod(_delegable(o),MT_TOSTRING,1,res)) {
+ if(type(res) == OT_STRING)
+ return;
+ //else keeps going to the default
+ }
+ }
+ default:
+ scsprintf(_sp(rsl(sizeof(void*)+20)),_SC("(%s : 0x%p)"),GetTypeName(o),(void*)_rawval(o));
+ }
+ res = SQString::Create(_ss(this),_spval);
+}
+
+
+bool SQVM::StringCat(const SQObjectPtr &str,const SQObjectPtr &obj,SQObjectPtr &dest)
+{
+ SQObjectPtr a, b;
+ ToString(str, a);
+ ToString(obj, b);
+ SQInteger l = _string(a)->_len , ol = _string(b)->_len;
+ SQChar *s = _sp(rsl(l + ol + 1));
+ memcpy(s, _stringval(a), rsl(l));
+ memcpy(s + l, _stringval(b), rsl(ol));
+ dest = SQString::Create(_ss(this), _spval, l + ol);
+ return true;
+}
+
+void SQVM::TypeOf(const SQObjectPtr &obj1,SQObjectPtr &dest)
+{
+ if(is_delegable(obj1) && _delegable(obj1)->_delegate) {
+ Push(obj1);
+ if(CallMetaMethod(_delegable(obj1),MT_TYPEOF,1,dest))
+ return;
+ }
+ dest = SQString::Create(_ss(this),GetTypeName(obj1));
+}
+
+bool SQVM::Init(SQVM *friendvm, SQInteger stacksize)
+{
+ _stack.resize(stacksize);
+ _alloccallsstacksize = 4;
+ _callstackdata.resize(_alloccallsstacksize);
+ _callsstacksize = 0;
+ _callsstack = &_callstackdata[0];
+ _stackbase = 0;
+ _top = 0;
+ if(!friendvm)
+ _roottable = SQTable::Create(_ss(this), 0);
+ else {
+ _roottable = friendvm->_roottable;
+ _errorhandler = friendvm->_errorhandler;
+ _debughook = friendvm->_debughook;
+ }
+
+ sq_base_register(this);
+ return true;
+}
+
+extern SQInstructionDesc g_InstrDesc[];
+
+bool SQVM::StartCall(SQClosure *closure,SQInteger target,SQInteger args,SQInteger stackbase,bool tailcall)
+{
+ SQFunctionProto *func = _funcproto(closure->_function);
+
+ const SQInteger paramssize = func->_nparameters;
+ const SQInteger newtop = stackbase + func->_stacksize;
+ SQInteger nargs = args;
+ if (paramssize != nargs) {
+ SQInteger ndef = func->_ndefaultparams;
+ if(ndef && nargs < paramssize) {
+ SQInteger diff = paramssize - nargs;
+ for(SQInteger n = ndef - diff; n < ndef; n++) {
+ _stack._vals[stackbase + (nargs++)] = closure->_defaultparams[n];
+ }
+ }
+ else if(func->_varparams)
+ {
+ if (nargs < paramssize) {
+ Raise_Error(_SC("wrong number of parameters"));
+ return false;
+ }
+ for(SQInteger n = 0; n < nargs - paramssize; n++) {
+ _vargsstack.push_back(_stack._vals[stackbase+paramssize+n]);
+ _stack._vals[stackbase+paramssize+n] = _null_;
+ }
+ }
+ else {
+ Raise_Error(_SC("wrong number of parameters"));
+ return false;
+ }
+ }
+
+ if(type(closure->_env) == OT_WEAKREF) {
+ _stack._vals[stackbase] = _weakref(closure->_env)->_obj;
+ }
+
+ if (!tailcall) {
+ CallInfo lc;
+ lc._generator = NULL;
+ lc._etraps = 0;
+ lc._prevstkbase = (SQInt32) ( stackbase - _stackbase );
+ lc._target = (SQInt32) target;
+ lc._prevtop = (SQInt32) (_top - _stackbase);
+ lc._ncalls = 1;
+ lc._root = SQFalse;
+ PUSH_CALLINFO(this, lc);
+ }
+ else {
+ ci->_ncalls++;
+ }
+ ci->_vargs.size = (SQInt32)(nargs - paramssize);
+ ci->_vargs.base = (SQInt32)(_vargsstack.size()-(ci->_vargs.size));
+ ci->_closure = closure;
+ ci->_literals = func->_literals;
+ ci->_ip = func->_instructions;
+ //grows the stack if needed
+ if (((SQUnsignedInteger)newtop + (func->_stacksize<<1)) > _stack.size()) {
+ _stack.resize(_stack.size() + (func->_stacksize<<1));
+ }
+
+ _top = newtop;
+ _stackbase = stackbase;
+ if (type(_debughook) != OT_NULL && _rawval(_debughook) != _rawval(ci->_closure))
+ CallDebugHook(_SC('c'));
+ return true;
+}
+
+bool SQVM::Return(SQInteger _arg0, SQInteger _arg1, SQObjectPtr &retval)
+{
+ if (type(_debughook) != OT_NULL && _rawval(_debughook) != _rawval(ci->_closure))
+ for(SQInteger i=0;i<ci->_ncalls;i++)
+ CallDebugHook(_SC('r'));
+
+ SQBool broot = ci->_root;
+ SQInteger last_top = _top;
+ SQInteger target = ci->_target;
+ SQInteger oldstackbase = _stackbase;
+ _stackbase -= ci->_prevstkbase;
+ _top = _stackbase + ci->_prevtop;
+ if(ci->_vargs.size) PopVarArgs(ci->_vargs);
+ POP_CALLINFO(this);
+ if (broot) {
+ if (_arg0 != MAX_FUNC_STACKSIZE) retval = _stack._vals[oldstackbase+_arg1];
+ else retval = _null_;
+ }
+ else {
+ if(target != -1) { //-1 is when a class contructor ret value has to be ignored
+ if (_arg0 != MAX_FUNC_STACKSIZE)
+ STK(target) = _stack._vals[oldstackbase+_arg1];
+ else
+ STK(target) = _null_;
+ }
+ }
+
+ CLEARSTACK(last_top);
+ assert(oldstackbase >= _stackbase);
+ return broot?true:false;
+}
+
+#define _RET_ON_FAIL(exp) { if(!exp) return false; }
+
+bool SQVM::LOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr)
+{
+ _RET_ON_FAIL(ARITH_OP( op , target, a, incr));
+ a = target;
+ return true;
+}
+
+bool SQVM::PLOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr)
+{
+ SQObjectPtr trg;
+ _RET_ON_FAIL(ARITH_OP( op , trg, a, incr));
+ target = a;
+ a = trg;
+ return true;
+}
+
+bool SQVM::DerefInc(SQInteger op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix)
+{
+ SQObjectPtr tmp, tself = self, tkey = key;
+ if (!Get(tself, tkey, tmp, false, true)) { Raise_IdxError(tkey); return false; }
+ _RET_ON_FAIL(ARITH_OP( op , target, tmp, incr))
+ Set(tself, tkey, target,true);
+ if (postfix) target = tmp;
+ return true;
+}
+
+#define arg0 (_i_._arg0)
+#define arg1 (_i_._arg1)
+#define sarg1 (*((SQInt32 *)&_i_._arg1))
+#define arg2 (_i_._arg2)
+#define arg3 (_i_._arg3)
+#define sarg3 ((SQInteger)*((signed char *)&_i_._arg3))
+
+SQRESULT SQVM::Suspend()
+{
+ if (_suspended)
+ return sq_throwerror(this, _SC("cannot suspend an already suspended vm"));
+ if (_nnativecalls!=2)
+ return sq_throwerror(this, _SC("cannot suspend through native calls/metamethods"));
+ return SQ_SUSPEND_FLAG;
+}
+
+void SQVM::PopVarArgs(VarArgs &vargs)
+{
+ for(SQInteger n = 0; n< vargs.size; n++)
+ _vargsstack.pop_back();
+}
+
+#define _FINISH(howmuchtojump) {jump = howmuchtojump; return true; }
+bool SQVM::FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr
+&o3,SQObjectPtr &o4,SQInteger arg_2,int exitpos,int &jump)
+{
+ SQInteger nrefidx;
+ switch(type(o1)) {
+ case OT_TABLE:
+ if((nrefidx = _table(o1)->Next(false,o4, o2, o3)) == -1) _FINISH(exitpos);
+ o4 = (SQInteger)nrefidx; _FINISH(1);
+ case OT_ARRAY:
+ if((nrefidx = _array(o1)->Next(o4, o2, o3)) == -1) _FINISH(exitpos);
+ o4 = (SQInteger) nrefidx; _FINISH(1);
+ case OT_STRING:
+ if((nrefidx = _string(o1)->Next(o4, o2, o3)) == -1)_FINISH(exitpos);
+ o4 = (SQInteger)nrefidx; _FINISH(1);
+ case OT_CLASS:
+ if((nrefidx = _class(o1)->Next(o4, o2, o3)) == -1)_FINISH(exitpos);
+ o4 = (SQInteger)nrefidx; _FINISH(1);
+ case OT_USERDATA:
+ case OT_INSTANCE:
+ if(_delegable(o1)->_delegate) {
+ SQObjectPtr itr;
+ Push(o1);
+ Push(o4);
+ if(CallMetaMethod(_delegable(o1), MT_NEXTI, 2, itr)){
+ o4 = o2 = itr;
+ if(type(itr) == OT_NULL) _FINISH(exitpos);
+ if(!Get(o1, itr, o3, false,false)) {
+ Raise_Error(_SC("_nexti returned an invalid idx"));
+ return false;
+ }
+ _FINISH(1);
+ }
+ Raise_Error(_SC("_nexti failed"));
+ return false;
+ }
+ break;
+ case OT_GENERATOR:
+ if(_generator(o1)->_state == SQGenerator::eDead) _FINISH(exitpos);
+ if(_generator(o1)->_state == SQGenerator::eSuspended) {
+ SQInteger idx = 0;
+ if(type(o4) == OT_INTEGER) {
+ idx = _integer(o4) + 1;
+ }
+ o2 = idx;
+ o4 = idx;
+ _generator(o1)->Resume(this, arg_2+1);
+ _FINISH(0);
+ }
+ default:
+ Raise_Error(_SC("cannot iterate %s"), GetTypeName(o1));
+ }
+ return false; //cannot be hit(just to avoid warnings)
+}
+
+bool SQVM::DELEGATE_OP(SQObjectPtr &trg,SQObjectPtr &o1,SQObjectPtr &o2)
+{
+ if(type(o1) != OT_TABLE) { Raise_Error(_SC("delegating a '%s'"), GetTypeName(o1)); return false; }
+ switch(type(o2)) {
+ case OT_TABLE:
+ if(!_table(o1)->SetDelegate(_table(o2))){
+ Raise_Error(_SC("delegate cycle detected"));
+ return false;
+ }
+ break;
+ case OT_NULL:
+ _table(o1)->SetDelegate(NULL);
+ break;
+ default:
+ Raise_Error(_SC("using '%s' as delegate"), GetTypeName(o2));
+ return false;
+ break;
+ }
+ trg = o1;
+ return true;
+}
+#define COND_LITERAL (arg3!=0?ci->_literals[arg1]:STK(arg1))
+
+#define _GUARD(exp) { if(!exp) { Raise_Error(_lasterror); SQ_THROW();} }
+
+#define SQ_THROW() { goto exception_trap; }
+
+bool SQVM::CLOSURE_OP(SQObjectPtr &target, SQFunctionProto *func)
+{
+ SQInteger nouters;
+ SQClosure *closure = SQClosure::Create(_ss(this), func);
+ if((nouters = func->_noutervalues)) {
+ closure->_outervalues.reserve(nouters);
+ for(SQInteger i = 0; i<nouters; i++) {
+ SQOuterVar &v = func->_outervalues[i];
+ switch(v._type){
+ case otSYMBOL:
+ closure->_outervalues.push_back(_null_);
+ if(!Get(_stack._vals[_stackbase]/*STK(0)*/, v._src, closure->_outervalues.top(), false,true))
+ {Raise_IdxError(v._src); return false; }
+ break;
+ case otLOCAL:
+ closure->_outervalues.push_back(_stack._vals[_stackbase+_integer(v._src)]);
+ break;
+ case otOUTER:
+ closure->_outervalues.push_back(_closure(ci->_closure)->_outervalues[_integer(v._src)]);
+ break;
+ }
+ }
+ }
+ SQInteger ndefparams;
+ if((ndefparams = func->_ndefaultparams)) {
+ closure->_defaultparams.reserve(ndefparams);
+ for(SQInteger i = 0; i < ndefparams; i++) {
+ SQInteger spos = func->_defaultparams[i];
+ closure->_defaultparams.push_back(_stack._vals[_stackbase + spos]);
+ }
+ }
+ target = closure;
+ return true;
+
+}
+
+bool SQVM::GETVARGV_OP(SQObjectPtr &target,SQObjectPtr &index,CallInfo *ci)
+{
+ if(ci->_vargs.size == 0) {
+ Raise_Error(_SC("the function doesn't have var args"));
+ return false;
+ }
+ if(!sq_isnumeric(index)){
+ Raise_Error(_SC("indexing 'vargv' with %s"),GetTypeName(index));
+ return false;
+ }
+ SQInteger idx = tointeger(index);
+ if(idx < 0 || idx >= ci->_vargs.size){ Raise_Error(_SC("vargv index out of range")); return false; }
+ target = _vargsstack[ci->_vargs.base+idx];
+ return true;
+}
+
+bool SQVM::CLASS_OP(SQObjectPtr &target,SQInteger baseclass,SQInteger attributes)
+{
+ SQClass *base = NULL;
+ SQObjectPtr attrs;
+ if(baseclass != -1) {
+ if(type(_stack._vals[_stackbase+baseclass]) != OT_CLASS) { Raise_Error(_SC("trying to inherit from a %s"),GetTypeName(_stack._vals[_stackbase+baseclass])); return false; }
+ base = _class(_stack._vals[_stackbase + baseclass]);
+ }
+ if(attributes != MAX_FUNC_STACKSIZE) {
+ attrs = _stack._vals[_stackbase+attributes];
+ }
+ target = SQClass::Create(_ss(this),base);
+ if(type(_class(target)->_metamethods[MT_INHERITED]) != OT_NULL) {
+ int nparams = 2;
+ SQObjectPtr ret;
+ Push(target); Push(attrs);
+ Call(_class(target)->_metamethods[MT_INHERITED],nparams,_top - nparams, ret, false);
+ Pop(nparams);
+ }
+ _class(target)->_attributes = attrs;
+ return true;
+}
+
+
+
+bool SQVM::IsEqual(SQObjectPtr &o1,SQObjectPtr &o2,bool &res)
+{
+ if(type(o1) == type(o2)) {
+ res = ((_userpointer(o1) == _userpointer(o2)?true:false));
+ }
+ else {
+ if(sq_isnumeric(o1) && sq_isnumeric(o2)) {
+ SQInteger cmpres;
+ if(!ObjCmp(o1, o2,cmpres)) return false;
+ res = (cmpres == 0);
+ }
+ else {
+ res = false;
+ }
+ }
+ return true;
+}
+
+bool SQVM::IsFalse(SQObjectPtr &o)
+{
+ if((type(o) & SQOBJECT_CANBEFALSE) && ( (type(o) == OT_FLOAT) && (_float(o) == SQFloat(0.0)) )
+ || (_integer(o) == 0) ) { //OT_NULL|OT_INTEGER|OT_BOOL
+ return true;
+ }
+ return false;
+}
+
+bool SQVM::GETPARENT_OP(SQObjectPtr &o,SQObjectPtr &target)
+{
+ switch(type(o)) {
+ case OT_TABLE: target = _table(o)->_delegate?SQObjectPtr(_table(o)->_delegate):_null_;
+ break;
+ case OT_CLASS: target = _class(o)->_base?_class(o)->_base:_null_;
+ break;
+ default:
+ Raise_Error(_SC("the %s type doesn't have a parent slot"), GetTypeName(o));
+ return false;
+ }
+ return true;
+}
+
+bool SQVM::Execute(SQObjectPtr &closure, SQInteger target, SQInteger nargs, SQInteger stackbase,SQObjectPtr &outres, SQBool raiseerror,ExecutionType et)
+{
+ if ((_nnativecalls + 1) > MAX_NATIVE_CALLS) { Raise_Error(_SC("Native stack overflow")); return false; }
+ _nnativecalls++;
+ AutoDec ad(&_nnativecalls);
+ SQInteger traps = 0;
+ //temp_reg vars for OP_CALL
+ SQInteger ct_target;
+ SQInteger ct_stackbase;
+ bool ct_tailcall;
+
+ switch(et) {
+ case ET_CALL: {
+ SQInteger last_top = _top;
+ temp_reg = closure;
+ if(!StartCall(_closure(temp_reg), _top - nargs, nargs, stackbase, false)) {
+ //call the handler if there are no calls in the stack, if not relies on the previous node
+ if(ci == NULL) CallErrorHandler(_lasterror);
+ return false;
+ }
+ if (_funcproto(_closure(temp_reg)->_function)->_bgenerator) {
+ SQFunctionProto *f = _funcproto(_closure(temp_reg)->_function);
+ SQGenerator *gen = SQGenerator::Create(_ss(this), _closure(temp_reg));
+ _GUARD(gen->Yield(this));
+ Return(1, ci->_target, temp_reg);
+ outres = gen;
+ CLEARSTACK(last_top);
+ return true;
+ }
+ ci->_root = SQTrue;
+ }
+ break;
+ case ET_RESUME_GENERATOR: _generator(closure)->Resume(this, target); ci->_root = SQTrue; traps += ci->_etraps; break;
+ case ET_RESUME_VM:
+ case ET_RESUME_THROW_VM:
+ traps = _suspended_traps;
+ ci->_root = _suspended_root;
+ ci->_vargs = _suspend_varargs;
+ _suspended = SQFalse;
+ if(et == ET_RESUME_THROW_VM) { SQ_THROW(); }
+ break;
+ }
+
+exception_restore:
+ //
+ {
+ for(;;)
+ {
+ const SQInstruction &_i_ = *ci->_ip++;
+ //dumpstack(_stackbase);
+ //scprintf("\n[%d] %s %d %d %d %d\n",ci->_ip-ci->_iv->_vals,g_InstrDesc[_i_.op].name,arg0,arg1,arg2,arg3);
+ switch(_i_.op)
+ {
+ case _OP_LINE:
+ if(type(_debughook) != OT_NULL && _rawval(_debughook) != _rawval(ci->_closure))
+ CallDebugHook(_SC('l'),arg1);
+ continue;
+ case _OP_LOAD: TARGET = ci->_literals[arg1]; continue;
+ case _OP_LOADINT: TARGET = (SQInteger)arg1; continue;
+ case _OP_LOADFLOAT: TARGET = *((SQFloat *)&arg1); continue;
+ case _OP_DLOAD: TARGET = ci->_literals[arg1]; STK(arg2) = ci->_literals[arg3];continue;
+ case _OP_TAILCALL:
+ temp_reg = STK(arg1);
+ if (type(temp_reg) == OT_CLOSURE && !_funcproto(_closure(temp_reg)->_function)->_bgenerator){
+ ct_tailcall = true;
+ if(ci->_vargs.size) PopVarArgs(ci->_vargs);
+ for (SQInteger i = 0; i < arg3; i++) STK(i) = STK(arg2 + i);
+ ct_target = ci->_target;
+ ct_stackbase = _stackbase;
+ goto common_call;
+ }
+ case _OP_CALL: {
+ ct_tailcall = false;
+ ct_target = arg0;
+ temp_reg = STK(arg1);
+ ct_stackbase = _stackbase+arg2;
+
+common_call:
+ SQObjectPtr clo = temp_reg;
+ SQInteger last_top = _top;
+ switch (type(clo)) {
+ case OT_CLOSURE:{
+ _GUARD(StartCall(_closure(clo), ct_target, arg3, ct_stackbase, ct_tailcall));
+ if (_funcproto(_closure(clo)->_function)->_bgenerator) {
+ SQGenerator *gen = SQGenerator::Create(_ss(this), _closure(clo));
+ _GUARD(gen->Yield(this));
+ Return(1, ct_target, clo);
+ STK(ct_target) = gen;
+ CLEARSTACK(last_top);
+ continue;
+ }
+ }
+ continue;
+ case OT_NATIVECLOSURE: {
+ bool suspend;
+ _GUARD(CallNative(_nativeclosure(clo), arg3, ct_stackbase, clo,suspend));
+ if(suspend){
+ _suspended = SQTrue;
+ _suspended_target = ct_target;
+ _suspended_root = ci->_root;
+ _suspended_traps = traps;
+ _suspend_varargs = ci->_vargs;
+ outres = clo;
+ return true;
+ }
+ if(ct_target != -1) { //skip return value for constructors
+ STK(ct_target) = clo;
+ }
+ }
+ continue;
+ case OT_CLASS:{
+ SQObjectPtr inst;
+ _GUARD(CreateClassInstance(_class(clo),inst,temp_reg));
+ STK(ct_target) = inst;
+ ct_target = -1; //fakes return value target so that is not overwritten by the constructor
+ if(type(temp_reg) != OT_NULL) {
+ _stack._vals[ct_stackbase] = inst;
+ goto common_call; //hard core spaghetti code(reissues the OP_CALL to invoke the constructor)
+ }
+ }
+ break;
+ case OT_TABLE:
+ case OT_USERDATA:
+ case OT_INSTANCE:
+ {
+ Push(clo);
+ for (SQInteger i = 0; i < arg3; i++) Push(STK(arg2 + i));
+ if (_delegable(clo) && CallMetaMethod(_delegable(clo), MT_CALL, arg3+1, clo)){
+ STK(ct_target) = clo;
+ break;
+ }
+ Raise_Error(_SC("attempt to call '%s'"), GetTypeName(clo));
+ SQ_THROW();
+ }
+ default:
+ Raise_Error(_SC("attempt to call '%s'"), GetTypeName(clo));
+ SQ_THROW();
+ }
+ }
+ continue;
+ case _OP_PREPCALL:
+ case _OP_PREPCALLK:
+ {
+ SQObjectPtr &key = _i_.op == _OP_PREPCALLK?(ci->_literals)[arg1]:STK(arg1);
+ SQObjectPtr &o = STK(arg2);
+ if (!Get(o, key, temp_reg,false,true)) {
+ if(type(o) == OT_CLASS) { //hack?
+ if(_class_ddel->Get(key,temp_reg)) {
+ STK(arg3) = o;
+ TARGET = temp_reg;
+ continue;
+ }
+ }
+ { Raise_IdxError(key); SQ_THROW();}
+ }
+
+ STK(arg3) = type(o) == OT_CLASS?STK(0):o;
+ TARGET = temp_reg;
+ }
+ continue;
+ case _OP_GETK:
+ if (!Get(STK(arg2), ci->_literals[arg1], temp_reg, false,true)) { Raise_IdxError(ci->_literals[arg1]); SQ_THROW();}
+ TARGET = temp_reg;
+ continue;
+ case _OP_MOVE: TARGET = STK(arg1); continue;
+ case _OP_NEWSLOT:
+ _GUARD(NewSlot(STK(arg1), STK(arg2), STK(arg3),false));
+ if(arg0 != arg3) TARGET = STK(arg3);
+ continue;
+ case _OP_DELETE: _GUARD(DeleteSlot(STK(arg1), STK(arg2), TARGET)); continue;
+ case _OP_SET:
+ if (!Set(STK(arg1), STK(arg2), STK(arg3),true)) { Raise_IdxError(STK(arg2)); SQ_THROW(); }
+ if (arg0 != arg3) TARGET = STK(arg3);
+ continue;
+ case _OP_GET:
+ if (!Get(STK(arg1), STK(arg2), temp_reg, false,true)) { Raise_IdxError(STK(arg2)); SQ_THROW(); }
+ TARGET = temp_reg;
+ continue;
+ case _OP_EQ:{
+ bool res;
+ if(!IsEqual(STK(arg2),COND_LITERAL,res)) { SQ_THROW(); }
+ TARGET = res?_true_:_false_;
+ }continue;
+ case _OP_NE:{
+ bool res;
+ if(!IsEqual(STK(arg2),COND_LITERAL,res)) { SQ_THROW(); }
+ TARGET = (!res)?_true_:_false_;
+ } continue;
+ case _OP_ARITH: _GUARD(ARITH_OP( arg3 , temp_reg, STK(arg2), STK(arg1))); TARGET = temp_reg; continue;
+ case _OP_BITW: _GUARD(BW_OP( arg3,TARGET,STK(arg2),STK(arg1))); continue;
+ case _OP_RETURN:
+ if(ci->_generator) {
+ ci->_generator->Kill();
+ }
+ if(Return(arg0, arg1, temp_reg)){
+ assert(traps==0);
+ outres = temp_reg;
+ return true;
+ }
+ continue;
+ case _OP_LOADNULLS:{ for(SQInt32 n=0; n < arg1; n++) STK(arg0+n) = _null_; }continue;
+ case _OP_LOADROOTTABLE: TARGET = _roottable; continue;
+ case _OP_LOADBOOL: TARGET = arg1?_true_:_false_; continue;
+ case _OP_DMOVE: STK(arg0) = STK(arg1); STK(arg2) = STK(arg3); continue;
+ case _OP_JMP: ci->_ip += (sarg1); continue;
+ case _OP_JNZ: if(!IsFalse(STK(arg0))) ci->_ip+=(sarg1); continue;
+ case _OP_JZ: if(IsFalse(STK(arg0))) ci->_ip+=(sarg1); continue;
+ case _OP_LOADFREEVAR: TARGET = _closure(ci->_closure)->_outervalues[arg1]; continue;
+ case _OP_VARGC: TARGET = SQInteger(ci->_vargs.size); continue;
+ case _OP_GETVARGV:
+ if(!GETVARGV_OP(TARGET,STK(arg1),ci)) { SQ_THROW(); }
+ continue;
+ case _OP_NEWTABLE: TARGET = SQTable::Create(_ss(this), arg1); continue;
+ case _OP_NEWARRAY: TARGET = SQArray::Create(_ss(this), 0); _array(TARGET)->Reserve(arg1); continue;
+ case _OP_APPENDARRAY: _array(STK(arg0))->Append(COND_LITERAL); continue;
+ case _OP_GETPARENT: _GUARD(GETPARENT_OP(STK(arg1),TARGET)); continue;
+ case _OP_COMPARITH: _GUARD(DerefInc(arg3, TARGET, STK((((SQUnsignedInteger)arg1&0xFFFF0000)>>16)), STK(arg2), STK(arg1&0x0000FFFF), false)); continue;
+ case _OP_COMPARITHL: _GUARD(LOCAL_INC(arg3, TARGET, STK(arg1), STK(arg2))); continue;
+ case _OP_INC: {SQObjectPtr o(sarg3); _GUARD(DerefInc('+',TARGET, STK(arg1), STK(arg2), o, false));} continue;
+ case _OP_INCL: {SQObjectPtr o(sarg3); _GUARD(LOCAL_INC('+',TARGET, STK(arg1), o));} continue;
+ case _OP_PINC: {SQObjectPtr o(sarg3); _GUARD(DerefInc('+',TARGET, STK(arg1), STK(arg2), o, true));} continue;
+ case _OP_PINCL: {SQObjectPtr o(sarg3); _GUARD(PLOCAL_INC('+',TARGET, STK(arg1), o));} continue;
+ case _OP_CMP: _GUARD(CMP_OP((CmpOP)arg3,STK(arg2),STK(arg1),TARGET)) continue;
+ case _OP_EXISTS: TARGET = Get(STK(arg1), STK(arg2), temp_reg, true,false)?_true_:_false_;continue;
+ case _OP_INSTANCEOF:
+ if(type(STK(arg1)) != OT_CLASS || type(STK(arg2)) != OT_INSTANCE)
+ {Raise_Error(_SC("cannot apply instanceof between a %s and a %s"),GetTypeName(STK(arg1)),GetTypeName(STK(arg2))); SQ_THROW();}
+ TARGET = _instance(STK(arg2))->InstanceOf(_class(STK(arg1)))?_true_:_false_;
+ continue;
+ case _OP_AND:
+ if(IsFalse(STK(arg2))) {
+ TARGET = STK(arg2);
+ ci->_ip += (sarg1);
+ }
+ continue;
+ case _OP_OR:
+ if(!IsFalse(STK(arg2))) {
+ TARGET = STK(arg2);
+ ci->_ip += (sarg1);
+ }
+ continue;
+ case _OP_NEG: _GUARD(NEG_OP(TARGET,STK(arg1))); continue;
+ case _OP_NOT: TARGET = (IsFalse(STK(arg1))?_true_:_false_); continue;
+ case _OP_BWNOT:
+ if(type(STK(arg1)) == OT_INTEGER) {
+ SQInteger t = _integer(STK(arg1));
+ TARGET = SQInteger(~t);
+ continue;
+ }
+ Raise_Error(_SC("attempt to perform a bitwise op on a %s"), GetTypeName(STK(arg1)));
+ SQ_THROW();
+ case _OP_CLOSURE: {
+ SQClosure *c = ci->_closure._unVal.pClosure;
+ SQFunctionProto *fp = c->_function._unVal.pFunctionProto;
+ if(!CLOSURE_OP(TARGET,fp->_functions[arg1]._unVal.pFunctionProto)) { SQ_THROW(); }
+ continue;
+ }
+ case _OP_YIELD:{
+ if(ci->_generator) {
+ if(sarg1 != MAX_FUNC_STACKSIZE) temp_reg = STK(arg1);
+ _GUARD(ci->_generator->Yield(this));
+ traps -= ci->_etraps;
+ if(sarg1 != MAX_FUNC_STACKSIZE) STK(arg1) = temp_reg;
+ }
+ else { Raise_Error(_SC("trying to yield a '%s',only genenerator can be yielded"), GetTypeName(ci->_generator)); SQ_THROW();}
+ if(Return(arg0, arg1, temp_reg)){
+ assert(traps == 0);
+ outres = temp_reg;
+ return true;
+ }
+
+ }
+ continue;
+ case _OP_RESUME:
+ if(type(STK(arg1)) != OT_GENERATOR){ Raise_Error(_SC("trying to resume a '%s',only genenerator can be resumed"), GetTypeName(STK(arg1))); SQ_THROW();}
+ _GUARD(_generator(STK(arg1))->Resume(this, arg0));
+ traps += ci->_etraps;
+ continue;
+ case _OP_FOREACH:{ int tojump;
+ _GUARD(FOREACH_OP(STK(arg0),STK(arg2),STK(arg2+1),STK(arg2+2),arg2,sarg1,tojump));
+ ci->_ip += tojump; }
+ continue;
+ case _OP_POSTFOREACH:
+ assert(type(STK(arg0)) == OT_GENERATOR);
+ if(_generator(STK(arg0))->_state == SQGenerator::eDead)
+ ci->_ip += (sarg1 - 1);
+ continue;
+ case _OP_DELEGATE: _GUARD(DELEGATE_OP(TARGET,STK(arg1),STK(arg2))); continue;
+ case _OP_CLONE:
+ if(!Clone(STK(arg1), TARGET))
+ { Raise_Error(_SC("cloning a %s"), GetTypeName(STK(arg1))); SQ_THROW();}
+ continue;
+ case _OP_TYPEOF: TypeOf(STK(arg1), TARGET); continue;
+ case _OP_PUSHTRAP:{
+ SQInstruction *_iv = _funcproto(_closure(ci->_closure)->_function)->_instructions;
+ _etraps.push_back(SQExceptionTrap(_top,_stackbase, &_iv[(ci->_ip-_iv)+arg1], arg0)); traps++;
+ ci->_etraps++;
+ }
+ continue;
+ case _OP_POPTRAP: {
+ for(SQInteger i = 0; i < arg0; i++) {
+ _etraps.pop_back(); traps--;
+ ci->_etraps--;
+ }
+ }
+ continue;
+ case _OP_THROW: Raise_Error(TARGET); SQ_THROW(); continue;
+ case _OP_CLASS: _GUARD(CLASS_OP(TARGET,arg1,arg2)); continue;
+ case _OP_NEWSLOTA:
+ bool bstatic = (arg0&NEW_SLOT_STATIC_FLAG)?true:false;
+ if(type(STK(arg1)) == OT_CLASS) {
+ if(type(_class(STK(arg1))->_metamethods[MT_NEWMEMBER]) != OT_NULL ) {
+ Push(STK(arg1)); Push(STK(arg2)); Push(STK(arg3));
+ Push((arg0&NEW_SLOT_ATTRIBUTES_FLAG) ? STK(arg2-1) : _null_);
+ int nparams = 4;
+ if(Call(_class(STK(arg1))->_metamethods[MT_NEWMEMBER], nparams, _top - nparams, temp_reg,SQFalse)) {
+ Pop(nparams);
+ continue;
+ }
+ }
+ }
+ _GUARD(NewSlot(STK(arg1), STK(arg2), STK(arg3),bstatic));
+ if((arg0&NEW_SLOT_ATTRIBUTES_FLAG)) {
+ _class(STK(arg1))->SetAttributes(STK(arg2),STK(arg2-1));
+ }
+ continue;
+ }
+
+ }
+ }
+exception_trap:
+ {
+ SQObjectPtr currerror = _lasterror;
+// dumpstack(_stackbase);
+ SQInteger n = 0;
+ SQInteger last_top = _top;
+ if(ci) {
+ if(_ss(this)->_notifyallexceptions) CallErrorHandler(currerror);
+
+ if(traps) {
+ do {
+ if(ci->_etraps > 0) {
+ SQExceptionTrap &et = _etraps.top();
+ ci->_ip = et._ip;
+ _top = et._stacksize;
+ _stackbase = et._stackbase;
+ _stack._vals[_stackbase+et._extarget] = currerror;
+ _etraps.pop_back(); traps--; ci->_etraps--;
+ CLEARSTACK(last_top);
+ goto exception_restore;
+ }
+ //if is a native closure
+ if(type(ci->_closure) != OT_CLOSURE && n)
+ break;
+ if(ci->_generator) ci->_generator->Kill();
+ PopVarArgs(ci->_vargs);
+ POP_CALLINFO(this);
+ n++;
+ } while(_callsstacksize);
+ }
+ else {
+ //call the hook
+ if(raiseerror && !_ss(this)->_notifyallexceptions)
+ CallErrorHandler(currerror);
+ }
+ //remove call stack until a C function is found or the cstack is empty
+ if(ci) do {
+ SQBool exitafterthisone = ci->_root;
+ if(ci->_generator) ci->_generator->Kill();
+ _stackbase -= ci->_prevstkbase;
+ _top = _stackbase + ci->_prevtop;
+ PopVarArgs(ci->_vargs);
+ POP_CALLINFO(this);
+ if( (ci && type(ci->_closure) != OT_CLOSURE) || exitafterthisone) break;
+ } while(_callsstacksize);
+
+ CLEARSTACK(last_top);
+ }
+ _lasterror = currerror;
+ return false;
+ }
+ assert(0);
+}
+
+bool SQVM::CreateClassInstance(SQClass *theclass, SQObjectPtr &inst, SQObjectPtr &constructor)
+{
+ inst = theclass->CreateInstance();
+ if(!theclass->Get(_ss(this)->_constructoridx,constructor)) {
+ constructor = _null_;
+ }
+ return true;
+}
+
+void SQVM::CallErrorHandler(SQObjectPtr &error)
+{
+ if(type(_errorhandler) != OT_NULL) {
+ SQObjectPtr out;
+ Push(_roottable); Push(error);
+ Call(_errorhandler, 2, _top-2, out,SQFalse);
+ Pop(2);
+ }
+}
+
+void SQVM::CallDebugHook(SQInteger type,SQInteger forcedline)
+{
+ SQObjectPtr temp_reg;
+ SQInteger nparams=5;
+ SQFunctionProto *func=_funcproto(_closure(ci->_closure)->_function);
+ Push(_roottable); Push(type); Push(func->_sourcename); Push(forcedline?forcedline:func->GetLine(ci->_ip)); Push(func->_name);
+ Call(_debughook,nparams,_top-nparams,temp_reg,SQFalse);
+ Pop(nparams);
+}
+
+bool SQVM::CallNative(SQNativeClosure *nclosure,SQInteger nargs,SQInteger stackbase,SQObjectPtr &retval,bool &suspend)
+{
+ if (_nnativecalls + 1 > MAX_NATIVE_CALLS) { Raise_Error(_SC("Native stack overflow")); return false; }
+ SQInteger nparamscheck = nclosure->_nparamscheck;
+ if(((nparamscheck > 0) && (nparamscheck != nargs))
+ || ((nparamscheck < 0) && (nargs < (-nparamscheck)))) {
+ Raise_Error(_SC("wrong number of parameters"));
+ return false;
+ }
+
+ SQInteger tcs;
+ if((tcs = nclosure->_typecheck.size())) {
+ for(SQInteger i = 0; i < nargs && i < tcs; i++)
+ if((nclosure->_typecheck._vals[i] != -1) && !(type(_stack._vals[stackbase+i]) & nclosure->_typecheck[i])) {
+ Raise_ParamTypeError(i,nclosure->_typecheck._vals[i],type(_stack._vals[stackbase+i]));
+ return false;
+ }
+ }
+ _nnativecalls++;
+ if ((_top + MIN_STACK_OVERHEAD) > (SQInteger)_stack.size()) {
+ _stack.resize(_stack.size() + (MIN_STACK_OVERHEAD<<1));
+ }
+ SQInteger oldtop = _top;
+ SQInteger oldstackbase = _stackbase;
+ _top = stackbase + nargs;
+ CallInfo lci;
+ lci._closure = nclosure;
+ lci._generator = NULL;
+ lci._etraps = 0;
+ lci._prevstkbase = (SQInt32) (stackbase - _stackbase);
+ lci._ncalls = 1;
+ lci._prevtop = (SQInt32) (oldtop - oldstackbase);
+ PUSH_CALLINFO(this, lci);
+ _stackbase = stackbase;
+ //push free variables
+ SQInteger outers = nclosure->_outervalues.size();
+ for (SQInteger i = 0; i < outers; i++) {
+ Push(nclosure->_outervalues[i]);
+ }
+
+ if(type(nclosure->_env) == OT_WEAKREF) {
+ _stack[stackbase] = _weakref(nclosure->_env)->_obj;
+ }
+
+
+ SQInteger ret = (nclosure->_function)(this);
+ _nnativecalls--;
+ suspend = false;
+ if( ret == SQ_SUSPEND_FLAG) suspend = true;
+ else if (ret < 0) {
+ _stackbase = oldstackbase;
+ _top = oldtop;
+ POP_CALLINFO(this);
+ Raise_Error(_lasterror);
+ return false;
+ }
+
+ if (ret != 0){ retval = TOP(); TOP().Null(); }
+ else { retval = _null_; }
+ _stackbase = oldstackbase;
+ _top = oldtop;
+ POP_CALLINFO(this);
+ return true;
+}
+
+bool SQVM::Get(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest,bool raw, bool fetchroot)
+{
+ switch(type(self)){
+ case OT_TABLE:
+ if(_table(self)->Get(key,dest))return true;
+ break;
+ case OT_ARRAY:
+ if(sq_isnumeric(key)){
+ return _array(self)->Get(tointeger(key),dest);
+ }
+ break;
+ case OT_INSTANCE:
+ if(_instance(self)->Get(key,dest)) return true;
+ break;
+ default:break; //shut up compiler
+ }
+ if(FallBackGet(self,key,dest,raw)) return true;
+
+ if(fetchroot) {
+ if(_rawval(STK(0)) == _rawval(self) &&
+ type(STK(0)) == type(self)) {
+ return _table(_roottable)->Get(key,dest);
+ }
+ }
+ return false;
+}
+
+bool SQVM::FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest,bool raw)
+{
+ switch(type(self)){
+ case OT_CLASS:
+ return _class(self)->Get(key,dest);
+ break;
+ case OT_TABLE:
+ case OT_USERDATA:
+ //delegation
+ if(_delegable(self)->_delegate) {
+ if(Get(SQObjectPtr(_delegable(self)->_delegate),key,dest,raw,false))
+ return true;
+ if(raw)return false;
+ Push(self);Push(key);
+ if(CallMetaMethod(_delegable(self),MT_GET,2,dest))
+ return true;
+ }
+ if(type(self) == OT_TABLE) {
+ if(raw) return false;
+ return _table_ddel->Get(key,dest);
+ }
+ return false;
+ break;
+ case OT_ARRAY:
+ if(raw)return false;
+ return _array_ddel->Get(key,dest);
+ case OT_STRING:
+ if(sq_isnumeric(key)){
+ SQInteger n=tointeger(key);
+ if(abs((int)n)<_string(self)->_len){
+ if(n<0)n=_string(self)->_len-n;
+ dest=SQInteger(_stringval(self)[n]);
+ return true;
+ }
+ return false;
+ }
+ else {
+ if(raw)return false;
+ return _string_ddel->Get(key,dest);
+ }
+ break;
+ case OT_INSTANCE:
+ if(raw)return false;
+ Push(self);Push(key);
+ if(!CallMetaMethod(_delegable(self),MT_GET,2,dest)) {
+ return _instance_ddel->Get(key,dest);
+ }
+ return true;
+ case OT_INTEGER:case OT_FLOAT:case OT_BOOL:
+ if(raw)return false;
+ return _number_ddel->Get(key,dest);
+ case OT_GENERATOR:
+ if(raw)return false;
+ return _generator_ddel->Get(key,dest);
+ case OT_CLOSURE: case OT_NATIVECLOSURE:
+ if(raw)return false;
+ return _closure_ddel->Get(key,dest);
+ case OT_THREAD:
+ if(raw)return false;
+ return _thread_ddel->Get(key,dest);
+ case OT_WEAKREF:
+ if(raw)return false;
+ return _weakref_ddel->Get(key,dest);
+ default:return false;
+ }
+ return false;
+}
+
+bool SQVM::Set(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val,bool fetchroot)
+{
+ switch(type(self)){
+ case OT_TABLE:
+ if(_table(self)->Set(key,val))
+ return true;
+ if(_table(self)->_delegate) {
+ if(Set(_table(self)->_delegate,key,val,false)) {
+ return true;
+ }
+ }
+ //keeps going
+ case OT_USERDATA:
+ if(_delegable(self)->_delegate) {
+ SQObjectPtr t;
+ Push(self);Push(key);Push(val);
+ if(CallMetaMethod(_delegable(self),MT_SET,3,t)) return true;
+ }
+ break;
+ case OT_INSTANCE:{
+ if(_instance(self)->Set(key,val))
+ return true;
+ SQObjectPtr t;
+ Push(self);Push(key);Push(val);
+ if(CallMetaMethod(_delegable(self),MT_SET,3,t)) return true;
+ }
+ break;
+ case OT_ARRAY:
+ if(!sq_isnumeric(key)) {Raise_Error(_SC("indexing %s with %s"),GetTypeName(self),GetTypeName(key)); return false; }
+ return _array(self)->Set(tointeger(key),val);
+ default:
+ Raise_Error(_SC("trying to set '%s'"),GetTypeName(self));
+ return false;
+ }
+ if(fetchroot) {
+ if(_rawval(STK(0)) == _rawval(self) &&
+ type(STK(0)) == type(self)) {
+ return _table(_roottable)->Set(key,val);
+ }
+ }
+ return false;
+}
+
+bool SQVM::Clone(const SQObjectPtr &self,SQObjectPtr &target)
+{
+ SQObjectPtr temp_reg;
+ SQObjectPtr newobj;
+ switch(type(self)){
+ case OT_TABLE:
+ newobj = _table(self)->Clone();
+ goto cloned_mt;
+ case OT_INSTANCE:
+ newobj = _instance(self)->Clone(_ss(this));
+cloned_mt:
+ if(_delegable(newobj)->_delegate){
+ Push(newobj);
+ Push(self);
+ CallMetaMethod(_delegable(newobj),MT_CLONED,2,temp_reg);
+ }
+ target = newobj;
+ return true;
+ case OT_ARRAY:
+ target = _array(self)->Clone();
+ return true;
+ default: return false;
+ }
+}
+
+bool SQVM::NewSlot(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic)
+{
+ if(type(key) == OT_NULL) { Raise_Error(_SC("null cannot be used as index")); return false; }
+ switch(type(self)) {
+ case OT_TABLE: {
+ bool rawcall = true;
+ if(_table(self)->_delegate) {
+ SQObjectPtr res;
+ if(!_table(self)->Get(key,res)) {
+ Push(self);Push(key);Push(val);
+ rawcall = !CallMetaMethod(_table(self),MT_NEWSLOT,3,res);
+ }
+ }
+ if(rawcall) _table(self)->NewSlot(key,val); //cannot fail
+
+ break;}
+ case OT_INSTANCE: {
+ SQObjectPtr res;
+ Push(self);Push(key);Push(val);
+ if(!CallMetaMethod(_instance(self),MT_NEWSLOT,3,res)) {
+ Raise_Error(_SC("class instances do not support the new slot operator"));
+ return false;
+ }
+ break;}
+ case OT_CLASS:
+ if(!_class(self)->NewSlot(_ss(this),key,val,bstatic)) {
+ if(_class(self)->_locked) {
+ Raise_Error(_SC("trying to modify a class that has already been instantiated"));
+ return false;
+ }
+ else {
+ SQObjectPtr oval = PrintObjVal(key);
+ Raise_Error(_SC("the property '%s' already exists"),_stringval(oval));
+ return false;
+ }
+ }
+ break;
+ default:
+ Raise_Error(_SC("indexing %s with %s"),GetTypeName(self),GetTypeName(key));
+ return false;
+ break;
+ }
+ return true;
+}
+
+bool SQVM::DeleteSlot(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &res)
+{
+ switch(type(self)) {
+ case OT_TABLE:
+ case OT_INSTANCE:
+ case OT_USERDATA: {
+ SQObjectPtr t;
+ bool handled = false;
+ if(_delegable(self)->_delegate) {
+ Push(self);Push(key);
+ handled = CallMetaMethod(_delegable(self),MT_DELSLOT,2,t);
+ }
+
+ if(!handled) {
+ if(type(self) == OT_TABLE) {
+ if(_table(self)->Get(key,t)) {
+ _table(self)->Remove(key);
+ }
+ else {
+ Raise_IdxError((SQObject &)key);
+ return false;
+ }
+ }
+ else {
+ Raise_Error(_SC("cannot delete a slot from %s"),GetTypeName(self));
+ return false;
+ }
+ }
+ res = t;
+ }
+ break;
+ default:
+ Raise_Error(_SC("attempt to delete a slot from a %s"),GetTypeName(self));
+ return false;
+ }
+ return true;
+}
+
+bool SQVM::Call(SQObjectPtr &closure,SQInteger nparams,SQInteger stackbase,SQObjectPtr &outres,SQBool raiseerror)
+{
+#ifdef _DEBUG
+SQInteger prevstackbase = _stackbase;
+#endif
+ switch(type(closure)) {
+ case OT_CLOSURE:
+ return Execute(closure, _top - nparams, nparams, stackbase,outres,raiseerror);
+ break;
+ case OT_NATIVECLOSURE:{
+ bool suspend;
+ return CallNative(_nativeclosure(closure), nparams, stackbase, outres,suspend);
+
+ }
+ break;
+ case OT_CLASS: {
+ SQObjectPtr constr;
+ SQObjectPtr temp;
+ CreateClassInstance(_class(closure),outres,constr);
+ if(type(constr) != OT_NULL) {
+ _stack[stackbase] = outres;
+ return Call(constr,nparams,stackbase,temp,raiseerror);
+ }
+ return true;
+ }
+ break;
+ default:
+ return false;
+ }
+#ifdef _DEBUG
+ if(!_suspended) {
+ assert(_stackbase == prevstackbase);
+ }
+#endif
+ return true;
+}
+
+bool SQVM::CallMetaMethod(SQDelegable *del,SQMetaMethod mm,SQInteger nparams,SQObjectPtr &outres)
+{
+ SQObjectPtr closure;
+ if(del->GetMetaMethod(this, mm, closure)) {
+ if(Call(closure, nparams, _top - nparams, outres, SQFalse)) {
+ Pop(nparams);
+ return true;
+ }
+ }
+ Pop(nparams);
+ return false;
+}
+
+void SQVM::Remove(SQInteger n) {
+ n = (n >= 0)?n + _stackbase - 1:_top + n;
+ for(SQInteger i = n; i < _top; i++){
+ _stack[i] = _stack[i+1];
+ }
+ _stack[_top] = _null_;
+ _top--;
+}
+
+void SQVM::Pop() {
+ _stack[--_top] = _null_;
+}
+
+void SQVM::Pop(SQInteger n) {
+ for(SQInteger i = 0; i < n; i++){
+ _stack[--_top] = _null_;
+ }
+}
+
+void SQVM::Push(const SQObjectPtr &o) { _stack[_top++] = o; }
+SQObjectPtr &SQVM::Top() { return _stack[_top-1]; }
+SQObjectPtr &SQVM::PopGet() { return _stack[--_top]; }
+SQObjectPtr &SQVM::GetUp(SQInteger n) { return _stack[_top+n]; }
+SQObjectPtr &SQVM::GetAt(SQInteger n) { return _stack[n]; }
+
+#ifdef _DEBUG_DUMP
+void SQVM::dumpstack(SQInteger stackbase,bool dumpall)
+{
+ SQInteger size=dumpall?_stack.size():_top;
+ SQInteger n=0;
+ scprintf(_SC("\n>>>>stack dump<<<<\n"));
+ CallInfo &ci=_callsstack[_callsstacksize-1];
+ scprintf(_SC("IP: %p\n"),ci._ip);
+ scprintf(_SC("prev stack base: %d\n"),ci._prevstkbase);
+ scprintf(_SC("prev top: %d\n"),ci._prevtop);
+ for(SQInteger i=0;i<size;i++){
+ SQObjectPtr &obj=_stack[i];
+ if(stackbase==i)scprintf(_SC(">"));else scprintf(_SC(" "));
+ scprintf(_SC("[%d]:"),n);
+ switch(type(obj)){
+ case OT_FLOAT: scprintf(_SC("FLOAT %.3f"),_float(obj));break;
+ case OT_INTEGER: scprintf(_SC("INTEGER %d"),_integer(obj));break;
+ case OT_BOOL: scprintf(_SC("BOOL %s"),_integer(obj)?"true":"false");break;
+ case OT_STRING: scprintf(_SC("STRING %s"),_stringval(obj));break;
+ case OT_NULL: scprintf(_SC("NULL")); break;
+ case OT_TABLE: scprintf(_SC("TABLE %p[%p]"),_table(obj),_table(obj)->_delegate);break;
+ case OT_ARRAY: scprintf(_SC("ARRAY %p"),_array(obj));break;
+ case OT_CLOSURE: scprintf(_SC("CLOSURE [%p]"),_closure(obj));break;
+ case OT_NATIVECLOSURE: scprintf(_SC("NATIVECLOSURE"));break;
+ case OT_USERDATA: scprintf(_SC("USERDATA %p[%p]"),_userdataval(obj),_userdata(obj)->_delegate);break;
+ case OT_GENERATOR: scprintf(_SC("GENERATOR %p"),_generator(obj));break;
+ case OT_THREAD: scprintf(_SC("THREAD [%p]"),_thread(obj));break;
+ case OT_USERPOINTER: scprintf(_SC("USERPOINTER %p"),_userpointer(obj));break;
+ case OT_CLASS: scprintf(_SC("CLASS %p"),_class(obj));break;
+ case OT_INSTANCE: scprintf(_SC("INSTANCE %p"),_instance(obj));break;
+ case OT_WEAKREF: scprintf(_SC("WEAKERF %p"),_weakref(obj));break;
+ default:
+ assert(0);
+ break;
+ };
+ scprintf(_SC("\n"));
+ ++n;
+ }
+}
+
+
+
+#endif
--- /dev/null
+/* see copyright notice in squirrel.h */
+#ifndef _SQVM_H_
+#define _SQVM_H_
+
+#include "sqopcodes.h"
+#include "sqobject.h"
+#define MAX_NATIVE_CALLS 100
+#define MIN_STACK_OVERHEAD 10
+
+#define SQ_SUSPEND_FLAG -666
+//base lib
+void sq_base_register(HSQUIRRELVM v);
+
+struct SQExceptionTrap{
+ SQExceptionTrap() {}
+ SQExceptionTrap(SQInteger ss, SQInteger stackbase,SQInstruction *ip, SQInteger ex_target){ _stacksize = ss; _stackbase = stackbase; _ip = ip; _extarget = ex_target;}
+ SQExceptionTrap(const SQExceptionTrap &et) { (*this) = et; }
+ SQInteger _stackbase;
+ SQInteger _stacksize;
+ SQInstruction *_ip;
+ SQInteger _extarget;
+};
+
+#define _INLINE
+
+#define STK(a) _stack._vals[_stackbase+(a)]
+#define TARGET _stack._vals[_stackbase+arg0]
+
+typedef sqvector<SQExceptionTrap> ExceptionsTraps;
+
+struct SQVM : public CHAINABLE_OBJ
+{
+ struct VarArgs {
+ VarArgs() { size = 0; base = 0; }
+ unsigned short size;
+ unsigned short base;
+ };
+
+ struct CallInfo{
+ //CallInfo() { _generator._type = OT_NULL;}
+ SQInstruction *_ip;
+ SQObjectPtr *_literals;
+ SQObjectPtr _closure;
+ SQGenerator *_generator;
+ SQInt32 _etraps;
+ SQInt32 _prevstkbase;
+ SQInt32 _prevtop;
+ SQInt32 _target;
+ SQInt32 _ncalls;
+ SQBool _root;
+ VarArgs _vargs;
+ };
+
+typedef sqvector<CallInfo> CallInfoVec;
+public:
+ enum ExecutionType { ET_CALL, ET_RESUME_GENERATOR, ET_RESUME_VM, ET_RESUME_THROW_VM };
+ SQVM(SQSharedState *ss);
+ ~SQVM();
+ bool Init(SQVM *friendvm, SQInteger stacksize);
+ bool Execute(SQObjectPtr &func, SQInteger target, SQInteger nargs, SQInteger stackbase, SQObjectPtr &outres, SQBool raiseerror, ExecutionType et = ET_CALL);
+ //starts a native call return when the NATIVE closure returns
+ bool CallNative(SQNativeClosure *nclosure, SQInteger nargs, SQInteger stackbase, SQObjectPtr &retval,bool &suspend);
+ //starts a SQUIRREL call in the same "Execution loop"
+ bool StartCall(SQClosure *closure, SQInteger target, SQInteger nargs, SQInteger stackbase, bool tailcall);
+ bool CreateClassInstance(SQClass *theclass, SQObjectPtr &inst, SQObjectPtr &constructor);
+ //call a generic closure pure SQUIRREL or NATIVE
+ bool Call(SQObjectPtr &closure, SQInteger nparams, SQInteger stackbase, SQObjectPtr &outres,SQBool raiseerror);
+ SQRESULT Suspend();
+
+ void CallDebugHook(SQInteger type,SQInteger forcedline=0);
+ void CallErrorHandler(SQObjectPtr &e);
+ bool Get(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &dest, bool raw, bool fetchroot);
+ bool FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest,bool raw);
+ bool Set(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val, bool fetchroot);
+ bool NewSlot(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val,bool bstatic);
+ bool DeleteSlot(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &res);
+ bool Clone(const SQObjectPtr &self, SQObjectPtr &target);
+ bool ObjCmp(const SQObjectPtr &o1, const SQObjectPtr &o2,SQInteger &res);
+ bool StringCat(const SQObjectPtr &str, const SQObjectPtr &obj, SQObjectPtr &dest);
+ bool IsEqual(SQObjectPtr &o1,SQObjectPtr &o2,bool &res);
+ void ToString(const SQObjectPtr &o,SQObjectPtr &res);
+ SQString *PrintObjVal(const SQObject &o);
+
+
+ void Raise_Error(const SQChar *s, ...);
+ void Raise_Error(SQObjectPtr &desc);
+ void Raise_IdxError(SQObject &o);
+ void Raise_CompareError(const SQObject &o1, const SQObject &o2);
+ void Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type);
+
+ void TypeOf(const SQObjectPtr &obj1, SQObjectPtr &dest);
+ bool CallMetaMethod(SQDelegable *del, SQMetaMethod mm, SQInteger nparams, SQObjectPtr &outres);
+ bool ArithMetaMethod(SQInteger op, const SQObjectPtr &o1, const SQObjectPtr &o2, SQObjectPtr &dest);
+ bool Return(SQInteger _arg0, SQInteger _arg1, SQObjectPtr &retval);
+ //new stuff
+ _INLINE bool ARITH_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2);
+ _INLINE bool BW_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2);
+ _INLINE bool NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o1);
+ _INLINE bool CMP_OP(CmpOP op, const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &res);
+ bool CLOSURE_OP(SQObjectPtr &target, SQFunctionProto *func);
+ bool GETVARGV_OP(SQObjectPtr &target,SQObjectPtr &idx,CallInfo *ci);
+ bool CLASS_OP(SQObjectPtr &target,SQInteger base,SQInteger attrs);
+ bool GETPARENT_OP(SQObjectPtr &o,SQObjectPtr &target);
+ //return true if the loop is finished
+ bool FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr &o3,SQObjectPtr &o4,SQInteger arg_2,int exitpos,int &jump);
+ bool DELEGATE_OP(SQObjectPtr &trg,SQObjectPtr &o1,SQObjectPtr &o2);
+ _INLINE bool LOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr);
+ _INLINE bool PLOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr);
+ _INLINE bool DerefInc(SQInteger op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix);
+ void PopVarArgs(VarArgs &vargs);
+ void ClearStack(SQInteger last_top);
+#ifdef _DEBUG_DUMP
+ void dumpstack(SQInteger stackbase=-1, bool dumpall = false);
+#endif
+
+#ifndef NO_GARBAGE_COLLECTOR
+ void Mark(SQCollectable **chain);
+#endif
+ void Finalize();
+ void GrowCallStack() {
+ SQInteger newsize = _alloccallsstacksize*2;
+ _callstackdata.resize(newsize);
+ _callsstack = &_callstackdata[0];
+ _alloccallsstacksize = newsize;
+ }
+ void Release(){ sq_delete(this,SQVM); } //does nothing
+////////////////////////////////////////////////////////////////////////////
+ //stack functions for the api
+ void Remove(SQInteger n);
+
+ bool IsFalse(SQObjectPtr &o);
+
+ void Pop();
+ void Pop(SQInteger n);
+ void Push(const SQObjectPtr &o);
+ SQObjectPtr &Top();
+ SQObjectPtr &PopGet();
+ SQObjectPtr &GetUp(SQInteger n);
+ SQObjectPtr &GetAt(SQInteger n);
+
+ SQObjectPtrVec _stack;
+ SQObjectPtrVec _vargsstack;
+ SQInteger _top;
+ SQInteger _stackbase;
+ SQObjectPtr _roottable;
+ SQObjectPtr _lasterror;
+ SQObjectPtr _errorhandler;
+ SQObjectPtr _debughook;
+
+ SQObjectPtr temp_reg;
+
+
+ CallInfo* _callsstack;
+ SQInteger _callsstacksize;
+ SQInteger _alloccallsstacksize;
+ sqvector<CallInfo> _callstackdata;
+
+ ExceptionsTraps _etraps;
+ CallInfo *ci;
+ void *_foreignptr;
+ //VMs sharing the same state
+ SQSharedState *_sharedstate;
+ SQInteger _nnativecalls;
+ //suspend infos
+ SQBool _suspended;
+ SQBool _suspended_root;
+ SQInteger _suspended_target;
+ SQInteger _suspended_traps;
+ VarArgs _suspend_varargs;
+};
+
+struct AutoDec{
+ AutoDec(SQInteger *n) { _n = n; }
+ ~AutoDec() { (*_n)--; }
+ SQInteger *_n;
+};
+
+inline SQObjectPtr &stack_get(HSQUIRRELVM v,SQInteger idx){return ((idx>=0)?(v->GetAt(idx+v->_stackbase-1)):(v->GetUp(idx)));}
+
+#define _ss(_vm_) (_vm_)->_sharedstate
+
+#ifndef NO_GARBAGE_COLLECTOR
+#define _opt_ss(_vm_) (_vm_)->_sharedstate
+#else
+#define _opt_ss(_vm_) NULL
+#endif
+
+#define PUSH_CALLINFO(v,nci){ \
+ if(v->_callsstacksize == v->_alloccallsstacksize) { \
+ v->GrowCallStack(); \
+ } \
+ v->ci = &v->_callsstack[v->_callsstacksize]; \
+ *(v->ci) = nci; \
+ v->_callsstacksize++; \
+}
+
+#define POP_CALLINFO(v){ \
+ v->_callsstacksize--; \
+ v->ci->_closure.Null(); \
+ if(v->_callsstacksize) \
+ v->ci = &v->_callsstack[v->_callsstacksize-1] ; \
+ else \
+ v->ci = NULL; \
+}
+#endif //_SQVM_H_
-// $Id$
-//
// SuperTux - Add-on
// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-//
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#include "addon/addon.hpp"
-#include <string>
-#include <sstream>
-#include <stdexcept>
#include <physfs.h>
+#include <stdexcept>
+#include <sstream>
+
+#include "addon/md5.hpp"
#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
#include "lisp/parser.hpp"
-#include "addon/addon.hpp"
-#include "log.hpp"
-#include "addon/md5.hpp"
+#include "lisp/writer.hpp"
+#include "util/log.hpp"
std::string
Addon::get_md5() const
}
void
-Addon::parse(const lisp::Lisp& lisp)
+Addon::parse(const Reader& lisp)
{
try {
lisp.get("kind", kind);
return true;
}
+/* EOF */
-// $Id$
-//
// SuperTux - Add-on
// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-//
-#ifndef ADDON_H
-#define ADDON_H
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_ADDON_ADDON_HPP
+#define HEADER_SUPERTUX_ADDON_ADDON_HPP
#include <string>
-#include <vector>
-namespace lisp {
-class Writer;
-class Lisp;
-}
+#include "util/reader_fwd.hpp"
+#include "util/writer_fwd.hpp"
/**
* Represents an (available or installed) Add-on, e.g. a level set
/**
* Read additional information from given contents of a (supertux-addoninfo ...) block
*/
- void parse(const lisp::Lisp& lisp);
+ void parse(const Reader& lisp);
/**
* Read additional information from given file
mutable std::string calculated_md5;
- Addon() {};
+ Addon() :
+ kind(),
+ title(),
+ author(),
+ license(),
+ http_url(),
+ suggested_filename(),
+ installed_physfs_filename(),
+ installed_absolute_filename(),
+ stored_md5(),
+ installed(),
+ loaded(),
+ calculated_md5()
+ {};
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux - Add-on Manager
// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-//
-
-#include <config.h>
-#include <version.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "addon/addon_manager.hpp"
-#include "addon/addon.hpp"
-#include "log.hpp"
-#include "lisp/parser.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/list_iterator.hpp"
-#include "lisp/writer.hpp"
+#include <config.h>
+#include <version.h>
-#include <stdexcept>
#include <algorithm>
-#include <stdlib.h>
#include <physfs.h>
+#include <sstream>
+#include <stdexcept>
#include <sys/stat.h>
#ifdef HAVE_LIBCURL
-#include <curl/curl.h>
-#include <curl/types.h>
-#include <curl/easy.h>
+# include <curl/curl.h>
+# include <curl/easy.h>
+# include <curl/types.h>
#endif
+#include "addon/addon.hpp"
+#include "lisp/list_iterator.hpp"
+#include "lisp/writer.hpp"
+#include "lisp/parser.hpp"
+#include "util/log.hpp"
+
#ifdef HAVE_LIBCURL
namespace {
- size_t my_curl_string_append(void *ptr, size_t size, size_t nmemb, void *string_ptr)
- {
- std::string& s = *static_cast<std::string*>(string_ptr);
- std::string buf(static_cast<char*>(ptr), size * nmemb);
- s += buf;
- log_debug << "read " << size * nmemb << " bytes of data..." << std::endl;
- return size * nmemb;
- }
+size_t my_curl_string_append(void *ptr, size_t size, size_t nmemb, void *string_ptr)
+{
+ std::string& s = *static_cast<std::string*>(string_ptr);
+ std::string buf(static_cast<char*>(ptr), size * nmemb);
+ s += buf;
+ log_debug << "read " << size * nmemb << " bytes of data..." << std::endl;
+ return size * nmemb;
+}
- size_t my_curl_physfs_write(void *ptr, size_t size, size_t nmemb, void *f_p)
- {
- PHYSFS_file* f = static_cast<PHYSFS_file*>(f_p);
- PHYSFS_sint64 written = PHYSFS_write(f, ptr, size, nmemb);
- log_debug << "read " << size * nmemb << " bytes of data..." << std::endl;
- return size * written;
- }
+size_t my_curl_physfs_write(void *ptr, size_t size, size_t nmemb, void *f_p)
+{
+ PHYSFS_file* f = static_cast<PHYSFS_file*>(f_p);
+ PHYSFS_sint64 written = PHYSFS_write(f, ptr, size, nmemb);
+ log_debug << "read " << size * nmemb << " bytes of data..." << std::endl;
+ return size * written;
+}
}
#endif
return instance;
}
-AddonManager::AddonManager()
+AddonManager::AddonManager() :
+ addons(),
+ ignored_addon_filenames()
{
#ifdef HAVE_LIBCURL
curl_global_init(CURL_GLOBAL_ALL);
std::vector<Addon*>
AddonManager::get_addons()
{
-/*
- for (std::vector<Addon>::iterator it = installed_addons.begin(); it != installed_addons.end(); ++it) {
+ /*
+ for (std::vector<Addon>::iterator it = installed_addons.begin(); it != installed_addons.end(); ++it) {
Addon& addon = *it;
if (addon.md5 == "") addon.md5 = calculate_md5(addon);
- }
-*/
+ }
+ */
return addons;
}
#endif
}
-
void
AddonManager::install(Addon* addon)
{
PHYSFS_freeList(rc);
}
-
void
-AddonManager::read(const lisp::Lisp& lisp)
+AddonManager::read(const Reader& lisp)
{
lisp.get("disabled-addons", ignored_addon_filenames);
}
writer.write("disabled-addons", ignored_addon_filenames);
}
+/* EOF */
-// $Id$
-//
// SuperTux - Add-on Manager
// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-//
-#ifndef ADDON_MANAGER_H
-#define ADDON_MANAGER_H
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_ADDON_ADDON_MANAGER_HPP
+#define HEADER_SUPERTUX_ADDON_ADDON_MANAGER_HPP
#include <string>
#include <vector>
-namespace lisp {
-class Lisp;
-class Writer;
-}
+
+#include "util/reader_fwd.hpp"
+#include "util/writer_fwd.hpp"
class Addon;
/**
* Read AddonManager configuration from Lisp
*/
- void read(const lisp::Lisp& lisp);
+ void read(const Reader& lisp);
protected:
std::vector<Addon*> addons;
};
#endif
+
+/* EOF */
// documentation and/or software.
//
-#include "md5.hpp"
+#include "addon/md5.hpp"
#include <assert.h>
-#include <strings.h>
-#include <iostream>
#include <stdexcept>
-MD5::MD5() {
+MD5::MD5() :
+ finalized()
+{
init();
}
count[1] += ((uint32_t)input_length >> 29);
-
buffer_space = 64 - buffer_index; // how much space is left in buffer
// Transform as many times as possible.
} else
input_index=0; // so we can buffer the whole input
-
// and here we do the buffering:
memcpy(buffer+buffer_index, input+input_index, input_length-input_index);
}
}
}
-
-MD5::MD5(FILE *file) {
+MD5::MD5(FILE *file) :
+ finalized()
+{
init(); // must be called be all constructors
update(file);
finalize ();
}
-MD5::MD5(std::istream& stream) {
+MD5::MD5(std::istream& stream) :
+ finalized()
+{
init(); // must called by all constructors
update (stream);
finalize();
}
-MD5::MD5(std::ifstream& stream) {
+MD5::MD5(std::ifstream& stream) :
+ finalized()
+{
init(); // must called by all constructors
update (stream);
finalize();
return stream;
}
-
// PRIVATE METHODS:
void MD5::init() {
a += I(b, c, d) + x + ac;
a = rotate_left (a, s) +b;
}
+
+/* EOF */
// documentation and/or software.
//
-#ifndef SUPERTUX_ADDON_MD5_HPP
-#define SUPERTUX_ADDON_MD5_HPP
+#ifndef HEADER_SUPERTUX_ADDON_MD5_HPP
+#define HEADER_SUPERTUX_ADDON_MD5_HPP
-#include <stdio.h>
#include <fstream>
-#include <iostream>
#include <stdint.h>
-#include <string>
class MD5 {
- public:
- MD5();
- MD5(uint8_t* string); /**< digest string, finalize */
- MD5(std::istream& stream); /**< digest stream, finalize */
- MD5(FILE *file); /**< digest file, close, finalize */
- MD5(std::ifstream& stream); /**< digest stream, close, finalize */
+public:
+ MD5();
+ MD5(uint8_t* string); /**< digest string, finalize */
+ MD5(std::istream& stream); /**< digest stream, finalize */
+ MD5(FILE *file); /**< digest file, close, finalize */
+ MD5(std::ifstream& stream); /**< digest stream, close, finalize */
- void update(uint8_t* input, unsigned int input_length); /**< MD5 block update operation. Continues an MD5 message-digest operation, processing another message block, and updating the context. */
- void update(std::istream& stream);
- void update(FILE *file);
- void update(std::ifstream& stream);
+ void update(uint8_t* input, unsigned int input_length); /**< MD5 block update operation. Continues an MD5 message-digest operation, processing another message block, and updating the context. */
+ void update(std::istream& stream);
+ void update(FILE *file);
+ void update(std::ifstream& stream);
- uint8_t* raw_digest(); /**< digest as a 16-byte binary array */
- std::string hex_digest(); /**< digest as a 33-byte ascii-hex string */
- friend std::ostream& operator<<(std::ostream&, MD5 context);
+ uint8_t* raw_digest(); /**< digest as a 16-byte binary array */
+ std::string hex_digest(); /**< digest as a 33-byte ascii-hex string */
+ friend std::ostream& operator<<(std::ostream&, MD5 context);
- private:
- uint32_t state[4];
- uint32_t count[2]; /**< number of _bits_, mod 2^64 */
- uint8_t buffer[64]; /**< input buffer */
- uint8_t digest[16];
- bool finalized;
+private:
+ uint32_t state[4];
+ uint32_t count[2]; /**< number of _bits_, mod 2^64 */
+ uint8_t buffer[64]; /**< input buffer */
+ uint8_t digest[16];
+ bool finalized;
- void init(); /**< called by all constructors */
- void finalize(); /**< MD5 finalization. Ends an MD5 message-digest operation, writing the the message digest and zeroizing the context. */
- void transform(uint8_t* buffer); /**< MD5 basic transformation. Transforms state based on block. Does the real update work. Note that length is implied to be 64. */
+ void init(); /**< called by all constructors */
+ void finalize(); /**< MD5 finalization. Ends an MD5 message-digest operation, writing the the message digest and zeroizing the context. */
+ void transform(uint8_t* buffer); /**< MD5 basic transformation. Transforms state based on block. Does the real update work. Note that length is implied to be 64. */
- static void encode(uint8_t* dest, uint32_t* src, uint32_t length); /**< Encodes input (uint32_t) into output (uint8_t). Assumes len is a multiple of 4. */
- static void decode(uint32_t* dest, uint8_t* src, uint32_t length); /**< Decodes input (uint8_t) into output (uint32_t). Assumes len is a multiple of 4. */
- static void memcpy(uint8_t* dest, uint8_t* src, uint32_t length);
- static void memset(uint8_t* start, uint8_t val, uint32_t length);
+ static void encode(uint8_t* dest, uint32_t* src, uint32_t length); /**< Encodes input (uint32_t) into output (uint8_t). Assumes len is a multiple of 4. */
+ static void decode(uint32_t* dest, uint8_t* src, uint32_t length); /**< Decodes input (uint8_t) into output (uint32_t). Assumes len is a multiple of 4. */
+ static void memcpy(uint8_t* dest, uint8_t* src, uint32_t length);
+ static void memset(uint8_t* start, uint8_t val, uint32_t length);
- static inline uint32_t rotate_left(uint32_t x, uint32_t n);
- static inline uint32_t F(uint32_t x, uint32_t y, uint32_t z); //*< F, G, H and I are basic MD5 functions. */
- static inline uint32_t G(uint32_t x, uint32_t y, uint32_t z);
- static inline uint32_t H(uint32_t x, uint32_t y, uint32_t z);
- static inline uint32_t I(uint32_t x, uint32_t y, uint32_t z);
- static inline void FF(uint32_t& a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac); /**< FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. Rotation is separate from addition to prevent recomputation. */
- static inline void GG(uint32_t& a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac);
- static inline void HH(uint32_t& a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac);
- static inline void II(uint32_t& a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac);
+ static inline uint32_t rotate_left(uint32_t x, uint32_t n);
+ static inline uint32_t F(uint32_t x, uint32_t y, uint32_t z); //*< F, G, H and I are basic MD5 functions. */
+ static inline uint32_t G(uint32_t x, uint32_t y, uint32_t z);
+ static inline uint32_t H(uint32_t x, uint32_t y, uint32_t z);
+ static inline uint32_t I(uint32_t x, uint32_t y, uint32_t z);
+ static inline void FF(uint32_t& a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac); /**< FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. Rotation is separate from addition to prevent recomputation. */
+ static inline void GG(uint32_t& a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac);
+ static inline void HH(uint32_t& a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac);
+ static inline void II(uint32_t& a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac);
};
#endif /*SUPERTUX_ADDON_MD5_HPP*/
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "dummy_sound_source.hpp"
-#include "sound_source.hpp"
+#include "audio/sound_source.hpp"
class DummySoundSource : public SoundSource
{
public:
- DummySoundSource()
+ DummySoundSource() :
+ is_playing()
{}
virtual ~DummySoundSource()
{}
{
return new DummySoundSource();
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#ifndef __DUMMY_SOUND_SOURCE_HPP__
-#define __DUMMY_SOUND_SOURCE_HPP__
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_AUDIO_DUMMY_SOUND_SOURCE_HPP
+#define HEADER_SUPERTUX_AUDIO_DUMMY_SOUND_SOURCE_HPP
class SoundSource;
SoundSource* create_dummy_sound_source();
#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include "audio/ogg_sound_file.hpp"
+
+OggSoundFile::OggSoundFile(PHYSFS_file* file, double loop_begin, double loop_at) :
+ file(),
+ vorbis_file(),
+ loop_begin(),
+ loop_at(),
+ normal_buffer_loop()
+{
+ this->file = file;
+
+ ov_callbacks callbacks = { cb_read, cb_seek, cb_close, cb_tell };
+ ov_open_callbacks(file, &vorbis_file, 0, 0, callbacks);
+
+ vorbis_info* vi = ov_info(&vorbis_file, -1);
+
+ channels = vi->channels;
+ rate = vi->rate;
+ bits_per_sample = 16;
+ size = static_cast<size_t> (ov_pcm_total(&vorbis_file, -1) * 2);
+
+ double samples_begin = loop_begin * rate;
+ double sample_loop = loop_at * rate;
+
+ this->loop_begin = (ogg_int64_t) samples_begin;
+ if(loop_begin < 0) {
+ this->loop_at = (ogg_int64_t) -1;
+ } else {
+ this->loop_at = (ogg_int64_t) sample_loop;
+ }
+}
+
+OggSoundFile::~OggSoundFile()
+{
+ ov_clear(&vorbis_file);
+}
+
+size_t
+OggSoundFile::read(void* _buffer, size_t buffer_size)
+{
+ char* buffer = reinterpret_cast<char*> (_buffer);
+ int section = 0;
+ size_t totalBytesRead = 0;
+
+ while(buffer_size>0) {
+#ifdef WORDS_BIGENDIAN
+ int bigendian = 1;
+#else
+ int bigendian = 0;
+#endif
+
+ size_t bytes_to_read = buffer_size;
+ if(loop_at > 0) {
+ size_t bytes_per_sample = 2;
+ ogg_int64_t time = ov_pcm_tell(&vorbis_file);
+ ogg_int64_t samples_left_till_loop = loop_at - time;
+ ogg_int64_t bytes_left_till_loop
+ = samples_left_till_loop * bytes_per_sample;
+ if(bytes_left_till_loop <= 4)
+ break;
+
+ if(bytes_left_till_loop < (ogg_int64_t) bytes_to_read) {
+ bytes_to_read = (size_t) bytes_left_till_loop;
+ }
+ }
+
+ long bytesRead
+ = ov_read(&vorbis_file, buffer, bytes_to_read, bigendian,
+ 2, 1, §ion);
+ if(bytesRead == 0) {
+ break;
+ }
+ buffer_size -= bytesRead;
+ buffer += bytesRead;
+ totalBytesRead += bytesRead;
+ }
+
+ return totalBytesRead;
+}
+
+void
+OggSoundFile::reset()
+{
+ ov_pcm_seek(&vorbis_file, loop_begin);
+}
+
+size_t
+OggSoundFile::cb_read(void* ptr, size_t size, size_t nmemb, void* source)
+{
+ PHYSFS_file* file = reinterpret_cast<PHYSFS_file*> (source);
+
+ PHYSFS_sint64 res
+ = PHYSFS_read(file, ptr, static_cast<PHYSFS_uint32> (size),
+ static_cast<PHYSFS_uint32> (nmemb));
+ if(res <= 0)
+ return 0;
+
+ return static_cast<size_t> (res);
+}
+
+int
+OggSoundFile::cb_seek(void* source, ogg_int64_t offset, int whence)
+{
+ PHYSFS_file* file = reinterpret_cast<PHYSFS_file*> (source);
+
+ switch(whence) {
+ case SEEK_SET:
+ if(PHYSFS_seek(file, static_cast<PHYSFS_uint64> (offset)) == 0)
+ return -1;
+ break;
+ case SEEK_CUR:
+ if(PHYSFS_seek(file, PHYSFS_tell(file) + offset) == 0)
+ return -1;
+ break;
+ case SEEK_END:
+ if(PHYSFS_seek(file, PHYSFS_fileLength(file) + offset) == 0)
+ return -1;
+ break;
+ default:
+#ifdef DEBUG
+ assert(false);
+#else
+ return -1;
+#endif
+ }
+ return 0;
+}
+
+int
+OggSoundFile::cb_close(void* source)
+{
+ PHYSFS_file* file = reinterpret_cast<PHYSFS_file*> (source);
+ PHYSFS_close(file);
+ return 0;
+}
+
+long
+OggSoundFile::cb_tell(void* source)
+{
+ PHYSFS_file* file = reinterpret_cast<PHYSFS_file*> (source);
+ return static_cast<long> (PHYSFS_tell(file));
+}
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_AUDIO_OGG_SOUND_FILE_HPP
+#define HEADER_SUPERTUX_AUDIO_OGG_SOUND_FILE_HPP
+
+#include <physfs.h>
+#include <vorbis/vorbisfile.h>
+
+#include "audio/sound_file.hpp"
+
+class OggSoundFile : public SoundFile
+{
+public:
+ OggSoundFile(PHYSFS_file* file, double loop_begin, double loop_at);
+ ~OggSoundFile();
+
+ size_t read(void* buffer, size_t buffer_size);
+ void reset();
+
+private:
+ static size_t cb_read(void* ptr, size_t size, size_t nmemb, void* source);
+ static int cb_seek(void* source, ogg_int64_t offset, int whence);
+ static int cb_close(void* source);
+ static long cb_tell(void* source);
+
+ PHYSFS_file* file;
+ OggVorbis_File vorbis_file;
+ ogg_int64_t loop_begin;
+ ogg_int64_t loop_at;
+ size_t normal_buffer_loop;
+
+private:
+ OggSoundFile(const OggSoundFile&);
+ OggSoundFile& operator=(const OggSoundFile&);
+};
+
+
+#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "openal_sound_source.hpp"
-#include "sound_manager.hpp"
-#include "math/vector.hpp"
+#include "audio/openal_sound_source.hpp"
+#include "audio/sound_manager.hpp"
-OpenALSoundSource::OpenALSoundSource()
+OpenALSoundSource::OpenALSoundSource() :
+ source()
{
alGenSources(1, &source);
SoundManager::check_al_error("Couldn't create audio source: ");
{
alSourcef(source, AL_ROLLOFF_FACTOR, factor);
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#ifndef __OPENAL_SOUND_SOURCE_H__
-#define __OPENAL_SOUND_SOURCE_H__
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_AUDIO_OPENAL_SOUND_SOURCE_HPP
+#define HEADER_SUPERTUX_AUDIO_OPENAL_SOUND_SOURCE_HPP
#include <al.h>
-#include "sound_source.hpp"
+#include "audio/sound_source.hpp"
class OpenALSoundSource : public SoundSource
{
};
#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include "audio/sound_error.hpp"
+
+SoundError::SoundError(const std::string& message_) throw() :
+ message(message_)
+{
+}
+
+SoundError::~SoundError() throw()
+{}
+
+const char*
+SoundError::what() const throw()
+{
+ return message.c_str();
+}
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_AUDIO_SOUND_ERROR_HPP
+#define HEADER_SUPERTUX_AUDIO_SOUND_ERROR_HPP
+
+#include <stdexcept>
+
+class SoundError : public std::exception
+{
+public:
+ SoundError(const std::string& message) throw();
+ virtual ~SoundError() throw();
+
+ const char* what() const throw();
+private:
+ std::string message;
+};
+
+#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
/** Used SDL_mixer and glest source as reference */
-#include <config.h>
-#include "sound_file.hpp"
+#include "audio/sound_file.hpp"
+
+#include <config.h>
-#include <stdio.h>
#include <stdint.h>
-#include <algorithm>
-#include <stdexcept>
#include <sstream>
-#include <assert.h>
-
#include <physfs.h>
-#include <vorbis/codec.h>
-#include <vorbis/vorbisfile.h>
-#include "log.hpp"
-#include "lisp/parser.hpp"
+#include "audio/sound_error.hpp"
+#include "audio/ogg_sound_file.hpp"
+#include "audio/wav_sound_file.hpp"
#include "lisp/lisp.hpp"
-#include "file_system.hpp"
-
-class SoundError : public std::exception
-{
-public:
- SoundError(const std::string& message) throw();
- virtual ~SoundError() throw();
-
- const char* what() const throw();
-private:
- std::string message;
-};
-
-SoundError::SoundError(const std::string& message) throw()
-{
- this->message = message;
-}
-
-SoundError::~SoundError() throw()
-{}
-
-const char*
-SoundError::what() const throw()
-{
- return message.c_str();
-}
-
-class WavSoundFile : public SoundFile
-{
-public:
- WavSoundFile(PHYSFS_file* file);
- ~WavSoundFile();
-
- size_t read(void* buffer, size_t buffer_size);
- void reset();
-
-private:
- PHYSFS_file* file;
-
- PHYSFS_sint64 datastart;
-};
-
-static inline uint32_t read32LE(PHYSFS_file* file)
-{
- uint32_t result;
- if(PHYSFS_readULE32(file, &result) == 0)
- throw SoundError("file too short");
-
- return result;
-}
-
-static inline uint16_t read16LE(PHYSFS_file* file)
-{
- uint16_t result;
- if(PHYSFS_readULE16(file, &result) == 0)
- throw SoundError("file too short");
-
- return result;
-}
-
-WavSoundFile::WavSoundFile(PHYSFS_file* file)
-{
- this->file = file;
-
- char magic[4];
- if(PHYSFS_read(file, magic, sizeof(magic), 1) != 1)
- throw SoundError("Couldn't read file magic (not a wave file)");
- if(strncmp(magic, "RIFF", 4) != 0) {
- log_debug << "MAGIC: " << magic << std::endl;
- throw SoundError("file is not a RIFF wav file");
- }
-
- uint32_t wavelen = read32LE(file);
- (void) wavelen;
-
- if(PHYSFS_read(file, magic, sizeof(magic), 1) != 1)
- throw SoundError("Couldn't read chunk header (not a wav file?)");
- if(strncmp(magic, "WAVE", 4) != 0)
- throw SoundError("file is not a valid RIFF/WAVE file");
-
- char chunkmagic[4];
- uint32_t chunklen;
-
- // search audio data format chunk
- do {
- if(PHYSFS_read(file, chunkmagic, sizeof(chunkmagic), 1) != 1)
- throw SoundError("EOF while searching format chunk");
- chunklen = read32LE(file);
-
- if(strncmp(chunkmagic, "fmt ", 4) == 0)
- break;
-
- if(strncmp(chunkmagic, "fact", 4) == 0
- || strncmp(chunkmagic, "LIST", 4) == 0) {
- // skip chunk
- if(PHYSFS_seek(file, PHYSFS_tell(file) + chunklen) == 0)
- throw SoundError("EOF while searching fmt chunk");
- } else {
- throw SoundError("complex WAVE files not supported");
- }
- } while(true);
-
- if(chunklen < 16)
- throw SoundError("Format chunk too short");
-
- // parse format
- uint16_t encoding = read16LE(file);
- if(encoding != 1)
- throw SoundError("only PCM encoding supported");
- channels = read16LE(file);
- rate = read32LE(file);
- uint32_t byterate = read32LE(file);
- (void) byterate;
- uint16_t blockalign = read16LE(file);
- (void) blockalign;
- bits_per_sample = read16LE(file);
-
- if(chunklen > 16) {
- if(PHYSFS_seek(file, PHYSFS_tell(file) + (chunklen-16)) == 0)
- throw SoundError("EOF while reading rest of format chunk");
- }
-
- // set file offset to DATA chunk data
- do {
- if(PHYSFS_read(file, chunkmagic, sizeof(chunkmagic), 1) != 1)
- throw SoundError("EOF while searching data chunk");
- chunklen = read32LE(file);
-
- if(strncmp(chunkmagic, "data", 4) == 0)
- break;
-
- // skip chunk
- if(PHYSFS_seek(file, PHYSFS_tell(file) + chunklen) == 0)
- throw SoundError("EOF while searching fmt chunk");
- } while(true);
-
- datastart = PHYSFS_tell(file);
- size = static_cast<size_t> (chunklen);
-}
-
-WavSoundFile::~WavSoundFile()
-{
- PHYSFS_close(file);
-}
-
-void
-WavSoundFile::reset()
-{
- if(PHYSFS_seek(file, datastart) == 0)
- throw SoundError("Couldn't seek to data start");
-}
-
-size_t
-WavSoundFile::read(void* buffer, size_t buffer_size)
-{
- PHYSFS_sint64 end = datastart + size;
- PHYSFS_sint64 cur = PHYSFS_tell(file);
- if(cur >= end)
- return 0;
-
- size_t readsize = std::min(static_cast<size_t> (end - cur), buffer_size);
- if(PHYSFS_read(file, buffer, readsize, 1) != 1)
- throw SoundError("read error while reading samples");
-
-#ifdef WORDS_BIGENDIAN
- if (bits_per_sample != 16)
- return readsize;
- char *tmp = (char*)buffer;
-
- size_t i;
- char c;
- for (i = 0; i < readsize / 2; i++)
- {
- c = tmp[2*i];
- tmp[2*i] = tmp[2*i+1];
- tmp[2*i+1] = c;
- }
-
- buffer = tmp;
-#endif
-
- return readsize;
-}
-
-//---------------------------------------------------------------------------
-
-class OggSoundFile : public SoundFile
-{
-public:
- OggSoundFile(PHYSFS_file* file, double loop_begin, double loop_at);
- ~OggSoundFile();
-
- size_t read(void* buffer, size_t buffer_size);
- void reset();
-
-private:
- static size_t cb_read(void* ptr, size_t size, size_t nmemb, void* source);
- static int cb_seek(void* source, ogg_int64_t offset, int whence);
- static int cb_close(void* source);
- static long cb_tell(void* source);
-
- PHYSFS_file* file;
- OggVorbis_File vorbis_file;
- ogg_int64_t loop_begin;
- ogg_int64_t loop_at;
- size_t normal_buffer_loop;
-};
-
-OggSoundFile::OggSoundFile(PHYSFS_file* file, double loop_begin, double loop_at)
-{
- this->file = file;
-
- ov_callbacks callbacks = { cb_read, cb_seek, cb_close, cb_tell };
- ov_open_callbacks(file, &vorbis_file, 0, 0, callbacks);
-
- vorbis_info* vi = ov_info(&vorbis_file, -1);
-
- channels = vi->channels;
- rate = vi->rate;
- bits_per_sample = 16;
- size = static_cast<size_t> (ov_pcm_total(&vorbis_file, -1) * 2);
-
- double samples_begin = loop_begin * rate;
- double sample_loop = loop_at * rate;
-
- this->loop_begin = (ogg_int64_t) samples_begin;
- if(loop_begin < 0) {
- this->loop_at = (ogg_int64_t) -1;
- } else {
- this->loop_at = (ogg_int64_t) sample_loop;
- }
-}
-
-OggSoundFile::~OggSoundFile()
-{
- ov_clear(&vorbis_file);
-}
-
-size_t
-OggSoundFile::read(void* _buffer, size_t buffer_size)
-{
- char* buffer = reinterpret_cast<char*> (_buffer);
- int section = 0;
- size_t totalBytesRead = 0;
-
- while(buffer_size>0) {
-#ifdef WORDS_BIGENDIAN
- int bigendian = 1;
-#else
- int bigendian = 0;
-#endif
-
- size_t bytes_to_read = buffer_size;
- if(loop_at > 0) {
- size_t bytes_per_sample = 2;
- ogg_int64_t time = ov_pcm_tell(&vorbis_file);
- ogg_int64_t samples_left_till_loop = loop_at - time;
- ogg_int64_t bytes_left_till_loop
- = samples_left_till_loop * bytes_per_sample;
- if(bytes_left_till_loop <= 4)
- break;
-
- if(bytes_left_till_loop < (ogg_int64_t) bytes_to_read) {
- bytes_to_read = (size_t) bytes_left_till_loop;
- }
- }
-
- long bytesRead
- = ov_read(&vorbis_file, buffer, bytes_to_read, bigendian,
- 2, 1, §ion);
- if(bytesRead == 0) {
- break;
- }
- buffer_size -= bytesRead;
- buffer += bytesRead;
- totalBytesRead += bytesRead;
- }
-
- return totalBytesRead;
-}
-
-void
-OggSoundFile::reset()
-{
- ov_pcm_seek(&vorbis_file, loop_begin);
-}
-
-size_t
-OggSoundFile::cb_read(void* ptr, size_t size, size_t nmemb, void* source)
-{
- PHYSFS_file* file = reinterpret_cast<PHYSFS_file*> (source);
-
- PHYSFS_sint64 res
- = PHYSFS_read(file, ptr, static_cast<PHYSFS_uint32> (size),
- static_cast<PHYSFS_uint32> (nmemb));
- if(res <= 0)
- return 0;
-
- return static_cast<size_t> (res);
-}
-
-int
-OggSoundFile::cb_seek(void* source, ogg_int64_t offset, int whence)
-{
- PHYSFS_file* file = reinterpret_cast<PHYSFS_file*> (source);
-
- switch(whence) {
- case SEEK_SET:
- if(PHYSFS_seek(file, static_cast<PHYSFS_uint64> (offset)) == 0)
- return -1;
- break;
- case SEEK_CUR:
- if(PHYSFS_seek(file, PHYSFS_tell(file) + offset) == 0)
- return -1;
- break;
- case SEEK_END:
- if(PHYSFS_seek(file, PHYSFS_fileLength(file) + offset) == 0)
- return -1;
- break;
- default:
-#ifdef DEBUG
- assert(false);
-#else
- return -1;
-#endif
- }
- return 0;
-}
-
-int
-OggSoundFile::cb_close(void* source)
-{
- PHYSFS_file* file = reinterpret_cast<PHYSFS_file*> (source);
- PHYSFS_close(file);
- return 0;
-}
-
-long
-OggSoundFile::cb_tell(void* source)
-{
- PHYSFS_file* file = reinterpret_cast<PHYSFS_file*> (source);
- return static_cast<long> (PHYSFS_tell(file));
-}
-
-//---------------------------------------------------------------------------
+#include "lisp/parser.hpp"
+#include "util/file_system.hpp"
+#include "util/log.hpp"
SoundFile* load_music_file(const std::string& filename)
{
SoundFile* load_sound_file(const std::string& filename)
{
if(filename.length() > 6
- && filename.compare(filename.length()-6, 6, ".music") == 0) {
+ && filename.compare(filename.length()-6, 6, ".music") == 0) {
return load_music_file(filename);
}
throw SoundError(msg.str());
}
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __SOUND_FILE_H__
-#define __SOUND_FILE_H__
+#ifndef HEADER_SUPERTUX_AUDIO_SOUND_FILE_HPP
+#define HEADER_SUPERTUX_AUDIO_SOUND_FILE_HPP
-#include <stdio.h>
#include <iostream>
class SoundFile
{
public:
+ SoundFile() :
+ channels(),
+ rate(),
+ bits_per_sample(),
+ size()
+ {}
+
virtual ~SoundFile()
{ }
SoundFile* load_sound_file(const std::string& filename);
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "sound_manager.hpp"
+#include "audio/sound_manager.hpp"
+#include <SDL.h>
+#include <assert.h>
#include <stdexcept>
-#include <iostream>
#include <sstream>
#include <memory>
-#include <assert.h>
-#include <SDL.h>
-#include "sound_file.hpp"
-#include "sound_source.hpp"
-#include "openal_sound_source.hpp"
-#include "stream_sound_source.hpp"
-#include "dummy_sound_source.hpp"
-#include "log.hpp"
-#include "timer.hpp"
+#include "audio/dummy_sound_source.hpp"
+#include "audio/sound_file.hpp"
+#include "audio/stream_sound_source.hpp"
+#include "util/log.hpp"
#ifndef DEBUG
- /** Older openal versions often miss this function and it isn't that vital for
- * supertux...
- */
+/** Older openal versions often miss this function and it isn't that vital for
+ * supertux...
+ */
#ifdef alcGetString
#undef alcGetString
#endif
SoundManager* sound_manager = 0;
-SoundManager::SoundManager()
- : device(0), context(0), sound_enabled(false), music_source(0),
- music_enabled(false)
+SoundManager::SoundManager() :
+ device(0),
+ context(0),
+ sound_enabled(false),
+ buffers(),
+ sources(),
+ update_list(),
+ music_source(0),
+ music_enabled(false),
+ current_music()
{
try {
device = alcOpenDevice(0);
try {
file->read(samples, file->size);
alBufferData(buffer, format, samples,
- static_cast<ALsizei> (file->size),
- static_cast<ALsizei> (file->rate));
+ static_cast<ALsizei> (file->size),
+ static_cast<ALsizei> (file->rate));
check_al_error("Couldn't fill audio buffer: ");
} catch(...) {
delete[] samples;
try {
std::auto_ptr<OpenALSoundSource> source
- (intern_create_sound_source(filename));
+ (intern_create_sound_source(filename));
if(pos == Vector(-1, -1)) {
source->set_rollof_factor(0);
{
if(fadetime > 0) {
if(music_source
- && music_source->get_fade_state() != StreamSoundSource::FadingOff)
+ && music_source->get_fade_state() != StreamSoundSource::FadingOff)
music_source->set_fading(StreamSoundSource::FadingOff, fadetime);
} else {
delete music_source;
throw std::runtime_error(msg.str());
}
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#ifndef __SOUND_MANAGER_H__
-#define __SOUND_MANAGER_H__
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_AUDIO_SOUND_MANAGER_HPP
+#define HEADER_SUPERTUX_AUDIO_SOUND_MANAGER_HPP
+#include <map>
#include <string>
#include <vector>
-#include <map>
-#include <alc.h>
#include <al.h>
+#include <alc.h>
#include "math/vector.hpp"
bool music_enabled;
std::string current_music;
+
+private:
+ SoundManager(const SoundManager&);
+ SoundManager& operator=(const SoundManager&);
};
extern SoundManager* sound_manager;
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#ifndef __SOUND_SOURCE_H__
-#define __SOUND_SOURCE_H__
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_AUDIO_SOUND_SOURCE_HPP
+#define HEADER_SUPERTUX_AUDIO_SOUND_SOURCE_HPP
class Vector;
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
-#include <assert.h>
-
-#include <SDL.h>
-
-#include "stream_sound_source.hpp"
-#include "sound_manager.hpp"
-#include "sound_file.hpp"
-#include "timer.hpp"
-#include "log.hpp"
-
-StreamSoundSource::StreamSoundSource()
- : file(0), fade_state(NoFading), looping(false)
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#include "audio/sound_file.hpp"
+#include "audio/sound_manager.hpp"
+#include "audio/stream_sound_source.hpp"
+#include "supertux/timer.hpp"
+#include "util/log.hpp"
+
+StreamSoundSource::StreamSoundSource() :
+ file(0),
+ fade_state(NoFading),
+ fade_start_time(),
+ fade_time(),
+ looping(false)
{
alGenBuffers(STREAMFRAGMENTS, buffers);
SoundManager::check_al_error("Couldn't allocate audio buffers: ");
size_t bytesread = 0;
do {
bytesread += file->read(bufferdata + bytesread,
- STREAMFRAGMENTSIZE - bytesread);
+ STREAMFRAGMENTSIZE - bytesread);
// end of sound file
if(bytesread < STREAMFRAGMENTSIZE) {
if(looping)
// return false if there aren't more buffers to fill
return bytesread >= STREAMFRAGMENTSIZE;
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __STREAM_SOUND_SOURCE_H__
-#define __STREAM_SOUND_SOURCE_H__
+#ifndef HEADER_SUPERTUX_AUDIO_STREAM_SOUND_SOURCE_HPP
+#define HEADER_SUPERTUX_AUDIO_STREAM_SOUND_SOURCE_HPP
-#include <stdio.h>
-#include <SDL.h>
-#include "openal_sound_source.hpp"
+#include "audio/openal_sound_source.hpp"
class SoundFile;
static const size_t STREAMBUFFERSIZE = 1024 * 500;
static const size_t STREAMFRAGMENTS = 5;
static const size_t STREAMFRAGMENTSIZE
- = STREAMBUFFERSIZE / STREAMFRAGMENTS;
+ = STREAMBUFFERSIZE / STREAMFRAGMENTS;
bool fillBufferAndQueue(ALuint buffer);
SoundFile* file;
float fade_start_time;
float fade_time;
bool looping;
+
+private:
+ StreamSoundSource(const StreamSoundSource&);
+ StreamSoundSource& operator=(const StreamSoundSource&);
};
#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include "audio/wav_sound_file.hpp"
+
+#include <string.h>
+#include <stdint.h>
+#include <assert.h>
+
+#include "audio/sound_error.hpp"
+#include "util/log.hpp"
+
+static inline uint32_t read32LE(PHYSFS_file* file)
+{
+ uint32_t result;
+ if(PHYSFS_readULE32(file, &result) == 0)
+ throw SoundError("file too short");
+
+ return result;
+}
+
+static inline uint16_t read16LE(PHYSFS_file* file)
+{
+ uint16_t result;
+ if(PHYSFS_readULE16(file, &result) == 0)
+ throw SoundError("file too short");
+
+ return result;
+}
+
+WavSoundFile::WavSoundFile(PHYSFS_file* file_) :
+ file(file_),
+ datastart()
+{
+ assert(file);
+ char magic[4];
+ if(PHYSFS_read(file, magic, sizeof(magic), 1) != 1)
+ throw SoundError("Couldn't read file magic (not a wave file)");
+ if(strncmp(magic, "RIFF", 4) != 0) {
+ log_debug << "MAGIC: " << magic << std::endl;
+ throw SoundError("file is not a RIFF wav file");
+ }
+
+ uint32_t wavelen = read32LE(file);
+ (void) wavelen;
+
+ if(PHYSFS_read(file, magic, sizeof(magic), 1) != 1)
+ throw SoundError("Couldn't read chunk header (not a wav file?)");
+ if(strncmp(magic, "WAVE", 4) != 0)
+ throw SoundError("file is not a valid RIFF/WAVE file");
+
+ char chunkmagic[4];
+ uint32_t chunklen;
+
+ // search audio data format chunk
+ do {
+ if(PHYSFS_read(file, chunkmagic, sizeof(chunkmagic), 1) != 1)
+ throw SoundError("EOF while searching format chunk");
+ chunklen = read32LE(file);
+
+ if(strncmp(chunkmagic, "fmt ", 4) == 0)
+ break;
+
+ if(strncmp(chunkmagic, "fact", 4) == 0
+ || strncmp(chunkmagic, "LIST", 4) == 0) {
+ // skip chunk
+ if(PHYSFS_seek(file, PHYSFS_tell(file) + chunklen) == 0)
+ throw SoundError("EOF while searching fmt chunk");
+ } else {
+ throw SoundError("complex WAVE files not supported");
+ }
+ } while(true);
+
+ if(chunklen < 16)
+ throw SoundError("Format chunk too short");
+
+ // parse format
+ uint16_t encoding = read16LE(file);
+ if(encoding != 1)
+ throw SoundError("only PCM encoding supported");
+ channels = read16LE(file);
+ rate = read32LE(file);
+ uint32_t byterate = read32LE(file);
+ (void) byterate;
+ uint16_t blockalign = read16LE(file);
+ (void) blockalign;
+ bits_per_sample = read16LE(file);
+
+ if(chunklen > 16) {
+ if(PHYSFS_seek(file, PHYSFS_tell(file) + (chunklen-16)) == 0)
+ throw SoundError("EOF while reading rest of format chunk");
+ }
+
+ // set file offset to DATA chunk data
+ do {
+ if(PHYSFS_read(file, chunkmagic, sizeof(chunkmagic), 1) != 1)
+ throw SoundError("EOF while searching data chunk");
+ chunklen = read32LE(file);
+
+ if(strncmp(chunkmagic, "data", 4) == 0)
+ break;
+
+ // skip chunk
+ if(PHYSFS_seek(file, PHYSFS_tell(file) + chunklen) == 0)
+ throw SoundError("EOF while searching fmt chunk");
+ } while(true);
+
+ datastart = PHYSFS_tell(file);
+ size = static_cast<size_t> (chunklen);
+}
+
+WavSoundFile::~WavSoundFile()
+{
+ PHYSFS_close(file);
+}
+
+void
+WavSoundFile::reset()
+{
+ if(PHYSFS_seek(file, datastart) == 0)
+ throw SoundError("Couldn't seek to data start");
+}
+
+size_t
+WavSoundFile::read(void* buffer, size_t buffer_size)
+{
+ PHYSFS_sint64 end = datastart + size;
+ PHYSFS_sint64 cur = PHYSFS_tell(file);
+ if(cur >= end)
+ return 0;
+
+ size_t readsize = std::min(static_cast<size_t> (end - cur), buffer_size);
+ if(PHYSFS_read(file, buffer, readsize, 1) != 1)
+ throw SoundError("read error while reading samples");
+
+#ifdef WORDS_BIGENDIAN
+ if (bits_per_sample != 16)
+ return readsize;
+ char *tmp = (char*)buffer;
+
+ size_t i;
+ char c;
+ for (i = 0; i < readsize / 2; i++)
+ {
+ c = tmp[2*i];
+ tmp[2*i] = tmp[2*i+1];
+ tmp[2*i+1] = c;
+ }
+
+ buffer = tmp;
+#endif
+
+ return readsize;
+}
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_AUDIO_WAV_SOUND_FILE_HPP
+#define HEADER_SUPERTUX_AUDIO_WAV_SOUND_FILE_HPP
+
+#include <physfs.h>
+
+#include "audio/sound_file.hpp"
+
+class WavSoundFile : public SoundFile
+{
+public:
+ WavSoundFile(PHYSFS_file* file);
+ ~WavSoundFile();
+
+ size_t read(void* buffer, size_t buffer_size);
+ void reset();
+
+private:
+ PHYSFS_file* file;
+
+ PHYSFS_sint64 datastart;
+
+private:
+ WavSoundFile(const WavSoundFile&);
+ WavSoundFile& operator=(const WavSoundFile&);
+};
+
+#endif
+
+/* EOF */
-// $Id$
-//
// AngryStone - A spiked block that charges towards the player
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "angrystone.hpp"
+#include "badguy/angrystone.hpp"
-#include "lisp/writer.hpp"
#include "object/player.hpp"
-#include "object_factory.hpp"
#include "sprite/sprite.hpp"
+#include "supertux/object_factory.hpp"
static const float SPEED = 240;
static const float ATTACK_TIME = 1;
static const float RECOVER_TIME = .5;
-AngryStone::AngryStone(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/angrystone/angrystone.sprite"), state(IDLE)
+AngryStone::AngryStone(const Reader& reader) :
+ BadGuy(reader, "images/creatures/angrystone/angrystone.sprite"),
+ attackDirection(),
+ oldWallDirection(),
+ timer(),
+ state(IDLE)
{
physic.set_velocity_x(0);
physic.set_velocity_y(0);
}
void
-AngryStone::write(lisp::Writer& writer)
-{
- writer.start_list("angrystone");
-
- writer.write("x", start_position.x);
- writer.write("y", start_position.y);
-
- writer.end_list("angrystone");
-}
-
-void
AngryStone::collision_solid(const CollisionHit& hit)
{
// TODO
state = CHARGING;
}
} else
- if ((dy > -playerHeight) && (dy < badguyHeight)) {
- if (dx > 0) {
- attackDirection.x = 1;
- attackDirection.y = 0;
- } else {
- attackDirection.x = -1;
- attackDirection.y = 0;
+ if ((dy > -playerHeight) && (dy < badguyHeight)) {
+ if (dx > 0) {
+ attackDirection.x = 1;
+ attackDirection.y = 0;
+ } else {
+ attackDirection.x = -1;
+ attackDirection.y = 0;
+ }
+ if ((attackDirection.x != oldWallDirection.x) || (attackDirection.y != oldWallDirection.y)) {
+ sprite->set_action("charging");
+ timer.start(CHARGE_TIME);
+ state = CHARGING;
+ }
}
- if ((attackDirection.x != oldWallDirection.x) || (attackDirection.y != oldWallDirection.y)) {
- sprite->set_action("charging");
- timer.start(CHARGE_TIME);
- state = CHARGING;
- }
- }
}
}
}
-IMPLEMENT_FACTORY(AngryStone, "angrystone")
+IMPLEMENT_FACTORY(AngryStone, "angrystone");
+
+/* EOF */
-// $Id$
-//
// AngryStone - A spiked block that charges towards the player
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __ANGRYSTONE_H__
-#define __ANGRYSTONE_H__
+#ifndef HEADER_SUPERTUX_BADGUY_ANGRYSTONE_HPP
+#define HEADER_SUPERTUX_BADGUY_ANGRYSTONE_HPP
-#include "badguy.hpp"
+#include "badguy/badguy.hpp"
class AngryStone : public BadGuy
{
public:
- AngryStone(const lisp::Lisp& reader);
+ AngryStone(const Reader& reader);
- void write(lisp::Writer& writer);
void collision_solid(const CollisionHit& hit);
HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
void active_update(float elapsed_time);
void kill_fall();
- virtual AngryStone* clone() const { return new AngryStone(*this); }
-
protected:
- Vector attackDirection; /**< 1-normalized vector of current attack direction */
- Vector oldWallDirection; /**< if wall was hit during last attack: 1-normalized vector of last attack direction, (0,0) otherwise */
-
- Timer timer;
-
enum AngryStoneState {
IDLE,
CHARGING,
ATTACKING,
RECOVERING
};
- AngryStoneState state;
+private:
+ Vector attackDirection; /**< 1-normalized vector of current attack direction */
+ Vector oldWallDirection; /**< if wall was hit during last attack: 1-normalized vector of last attack direction, (0,0) otherwise */
+ Timer timer;
+ AngryStoneState state;
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "badguy.hpp"
+#include "badguy/badguy.hpp"
#include "audio/sound_manager.hpp"
-#include "game_session.hpp"
-#include "level.hpp"
-#include "log.hpp"
-#include "main.hpp"
#include "object/bullet.hpp"
-#include "object/camera.hpp"
-#include "object/particles.hpp"
#include "object/player.hpp"
-#include "object/tilemap.hpp"
-#include "random_generator.hpp"
-#include "sector.hpp"
-#include "statistics.hpp"
-#include "tile.hpp"
+#include "supertux/level.hpp"
+#include "supertux/sector.hpp"
+#include "supertux/tile.hpp"
#include <math.h>
static const float X_OFFSCREEN_DISTANCE = 1600;
static const float Y_OFFSCREEN_DISTANCE = 1200;
-BadGuy::BadGuy(const Vector& pos, const std::string& sprite_name, int layer)
- : MovingSprite(pos, sprite_name, layer, COLGROUP_DISABLED), countMe(true), is_initialized(false),
- dir(LEFT), start_dir(AUTO), frozen(false), ignited(false),
- state(STATE_INIT), on_ground_flag(false), colgroup_active(COLGROUP_MOVING)
+BadGuy::BadGuy(const Vector& pos, const std::string& sprite_name, int layer) :
+ MovingSprite(pos, sprite_name, layer, COLGROUP_DISABLED),
+ countMe(true),
+ is_initialized(false),
+ start_position(),
+ dir(LEFT),
+ start_dir(AUTO),
+ frozen(false),
+ ignited(false),
+ dead_script(),
+ state(STATE_INIT),
+ is_active_flag(),
+ state_timer(),
+ on_ground_flag(false),
+ floor_normal(),
+ colgroup_active(COLGROUP_MOVING)
{
start_position = bbox.p1;
dir = (start_dir == AUTO) ? LEFT : start_dir;
}
-BadGuy::BadGuy(const Vector& pos, Direction direction, const std::string& sprite_name, int layer)
- : MovingSprite(pos, sprite_name, layer, COLGROUP_DISABLED), countMe(true), is_initialized(false),
- dir(direction), start_dir(direction), frozen(false), ignited(false),
- state(STATE_INIT), on_ground_flag(false), colgroup_active(COLGROUP_MOVING)
+BadGuy::BadGuy(const Vector& pos, Direction direction, const std::string& sprite_name, int layer) :
+ MovingSprite(pos, sprite_name, layer, COLGROUP_DISABLED),
+ countMe(true),
+ is_initialized(false),
+ start_position(),
+ dir(direction),
+ start_dir(direction),
+ frozen(false),
+ ignited(false),
+ dead_script(),
+ state(STATE_INIT),
+ is_active_flag(),
+ state_timer(),
+ on_ground_flag(false),
+ floor_normal(),
+ colgroup_active(COLGROUP_MOVING)
{
start_position = bbox.p1;
dir = (start_dir == AUTO) ? LEFT : start_dir;
}
-BadGuy::BadGuy(const lisp::Lisp& reader, const std::string& sprite_name, int layer)
- : MovingSprite(reader, sprite_name, layer, COLGROUP_DISABLED), countMe(true), is_initialized(false), dir(LEFT), start_dir(AUTO), frozen(false), ignited(false), state(STATE_INIT), on_ground_flag(false), colgroup_active(COLGROUP_MOVING)
+BadGuy::BadGuy(const Reader& reader, const std::string& sprite_name, int layer) :
+ MovingSprite(reader, sprite_name, layer, COLGROUP_DISABLED),
+ countMe(true),
+ is_initialized(false),
+ start_position(),
+ dir(LEFT),
+ start_dir(AUTO),
+ frozen(false),
+ ignited(false),
+ dead_script(),
+ state(STATE_INIT),
+ is_active_flag(),
+ state_timer(),
+ on_ground_flag(false),
+ floor_normal(),
+ colgroup_active(COLGROUP_MOVING)
{
start_position = bbox.p1;
void
BadGuy::draw(DrawingContext& context)
{
- if(!sprite)
+ if(!sprite.get())
return;
if(state == STATE_INIT || state == STATE_INACTIVE)
return;
}
void
-BadGuy::write(lisp::Writer& )
-{
- log_warning << "tried to write out a generic badguy" << std::endl;
-}
-
-void
BadGuy::active_update(float elapsed_time)
{
movement = physic.get_movement(elapsed_time);
BadGuy::run_dead_script()
{
if (countMe)
- Sector::current()->get_level()->stats.badguys++;
+ Sector::current()->get_level()->stats.badguys++;
countMe = false;
- // start dead-script
+ // start dead-script
if(dead_script != "") {
std::istringstream stream(dead_script);
Sector::current()->run_script(stream, "dead-script");
if (state == STATE_ACTIVE) set_group(group);
}
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __BADGUY_H__
-#define __BADGUY_H__
+#ifndef HEADER_SUPERTUX_BADGUY_BADGUY_HPP
+#define HEADER_SUPERTUX_BADGUY_BADGUY_HPP
-#include "timer.hpp"
#include "object/moving_sprite.hpp"
-#include "physic.hpp"
-#include "serializable.hpp"
-#include "direction.hpp"
+#include "supertux/direction.hpp"
+#include "supertux/physic.hpp"
+#include "supertux/timer.hpp"
class Player;
class Bullet;
-/**
- * Base class for moving sprites that can hurt the Player.
- */
-class BadGuy : public MovingSprite, protected UsesPhysic, public Serializable
+/** Base class for moving sprites that can hurt the Player. */
+class BadGuy : public MovingSprite
{
public:
BadGuy(const Vector& pos, const std::string& sprite_name, int layer = LAYER_OBJECTS);
BadGuy(const Vector& pos, Direction direction, const std::string& sprite_name, int layer = LAYER_OBJECTS);
- BadGuy(const lisp::Lisp& reader, const std::string& sprite_name, int layer = LAYER_OBJECTS);
+ BadGuy(const Reader& reader, const std::string& sprite_name, int layer = LAYER_OBJECTS);
- /** Called when the badguy is drawn. The default implementation simply draws
- * the badguy sprite on screen
- */
+ /** Called when the badguy is drawn. The default implementation
+ simply draws the badguy sprite on screen */
virtual void draw(DrawingContext& context);
- /** Called each frame. The default implementation checks badguy state and
- * calls active_update and inactive_update
- */
+
+ /** Called each frame. The default implementation checks badguy
+ state and calls active_update and inactive_update */
virtual void update(float elapsed_time);
- /** Called when a collision with another object occurred. The default
- * implementation calls collision_player, collision_solid, collision_badguy
- * and collision_squished
- */
+
+ /** Called when a collision with another object occurred. The
+ default implementation calls collision_player, collision_solid,
+ collision_badguy and collision_squished */
virtual HitResponse collision(GameObject& other, const CollisionHit& hit);
- /** Called when a collision with tile with special attributes occurred */
+ /** Called when a collision with tile with special attributes
+ occurred */
virtual void collision_tile(uint32_t tile_attributes);
- /** Set the badguy to kill/falling state, which makes him falling of the
- * screen (his sprite is turned upside-down)
- */
+ /** Set the badguy to kill/falling state, which makes him falling of
+ the screen (his sprite is turned upside-down) */
virtual void kill_fall();
/** Call this, if you use custom kill_fall() or kill_squashed(GameObject& object) */
virtual void run_dead_script();
- /** Writes out the badguy into the included lisp::Writer. Useful e.g. when
- * converting an old-format level to the new format.
- */
- virtual void write(lisp::Writer& writer);
-
- /**
- * True if this badguy can break bricks or open bonusblocks in his current form.
- */
+ /** True if this badguy can break bricks or open bonusblocks in his
+ current form. */
virtual bool can_break()
{
return false;
start_position = vec;
}
- /** Count this badguy to the statistics? This value should not be changed
- * during runtime. */
+ /** Count this badguy to the statistics? This value should not be
+ changed during runtime. */
bool countMe;
- /**
- * Called when hit by a fire bullet, and is_flammable() returns true
- */
+ /** Called when hit by a fire bullet, and is_flammable() returns true */
virtual void ignite();
- /**
- * Called to revert a badguy when is_ignited() returns true
- */
+ /** Called to revert a badguy when is_ignited() returns true */
virtual void extinguish();
- /**
- * Returns whether to call ignite() when a badguy gets hit by a fire bullet
- */
+ /** Returns whether to call ignite() when a badguy gets hit by a fire bullet */
virtual bool is_flammable() const;
- /**
- * Returns whether this badguys is currently on fire
- */
+ /** Returns whether this badguys is currently on fire */
bool is_ignited() const;
- /**
- * Called when hit by an ice bullet, and is_freezable() returns true.
- */
+ /** Called when hit by an ice bullet, and is_freezable() returns true. */
virtual void freeze();
- /**
- * Called to unfreeze the badguy.
- */
+ /** Called to unfreeze the badguy. */
virtual void unfreeze();
virtual bool is_freezable() const;
STATE_FALLING
};
+protected:
/** Called when the badguy collided with a player */
virtual HitResponse collision_player(Player& player, const CollisionHit& hit);
+
/** Called when the badguy collided with solid ground */
virtual void collision_solid(const CollisionHit& hit);
+
/** Called when the badguy collided with another badguy */
virtual HitResponse collision_badguy(BadGuy& other, const CollisionHit& hit);
- /** Called when the player hit the badguy from above. You should return true
- * if the badguy was squished, false if squishing wasn't possible
- */
+ /** Called when the player hit the badguy from above. You should
+ return true if the badguy was squished, false if squishing
+ wasn't possible */
virtual bool collision_squished(GameObject& object);
/** Called when the badguy collided with a bullet */
/** called each frame when the badguy is activated. */
virtual void active_update(float elapsed_time);
+
/** called each frame when the badguy is not activated. */
virtual void inactive_update(float elapsed_time);
- bool is_initialized; /**< true if initialize() has already been called */
+ /** true if initialize() has already been called */
+ bool is_initialized;
+
/** called immediately before the first call to initialize */
virtual void initialize();
- /**
- * called when the badguy has been activated. (As a side effect the dir
- * variable might have been changed so that it faces towards the player.
- */
+
+ /** called when the badguy has been activated. (As a side effect the
+ dir variable might have been changed so that it faces towards
+ the player. */
virtual void activate();
+
/** called when the badguy has been deactivated */
virtual void deactivate();
State get_state() const
{ return state; }
- /**
- * returns a pointer to the nearest player or 0 if no player is available
- */
+ /** returns a pointer to the nearest player or 0 if no player is available */
Player* get_nearest_player();
- /**
- * initial position of the enemy. Also the position where enemy respawns when
- * after being deactivated.
- */
+ /** initial position of the enemy. Also the position where enemy
+ respawns when after being deactivated. */
bool is_offscreen();
- /**
- * Returns true if we might soon fall at least @c height pixels. Minimum
- * value for height is 1 pixel
- */
+
+ /** Returns true if we might soon fall at least @c height
+ pixels. Minimum value for height is 1 pixel */
bool might_fall(int height = 1);
Vector start_position;
- /**
- * The direction we currently face in
- */
+ /** The direction we currently face in */
Direction dir;
- /**
- * The direction we initially faced in
- */
+ /** The direction we initially faced in */
Direction start_dir;
- /**
- * Get Direction from String.
- */
+ /** Get Direction from String. */
Direction str2dir( std::string dir_str );
- /**
- * Update on_ground_flag judging by solid collision @c hit.
- * This gets called from the base implementation of collision_solid, so call this when overriding collision_solid's default behaviour.
- */
+ /** Update on_ground_flag judging by solid collision @c hit. This
+ gets called from the base implementation of collision_solid, so
+ call this when overriding collision_solid's default
+ behaviour. */
void update_on_ground_flag(const CollisionHit& hit);
- /**
- * Returns true if we touched ground in the past frame
- * This only works if update_on_ground_flag() gets called in collision_solid.
- */
+ /** Returns true if we touched ground in the past frame This only
+ works if update_on_ground_flag() gets called in
+ collision_solid. */
bool on_ground();
- /**
- * Returns floor normal stored the last time when update_on_ground_flag was called and we touched something solid from above.
- */
+ /** Returns floor normal stored the last time when
+ update_on_ground_flag was called and we touched something solid
+ from above. */
Vector get_floor_normal();
bool frozen;
std::string dead_script; /**< script to execute when badguy is killed */
- /**
- * Returns true if we were in STATE_ACTIVE at the beginning of the last call to update()
- */
+ /** Returns true if we were in STATE_ACTIVE at the beginning of the
+ last call to update() */
bool is_active();
- void set_colgroup_active(CollisionGroup group); /**< changes colgroup_active. Also calls set_group when badguy is in STATE_ACTIVE */
+ /** changes colgroup_active. Also calls set_group when badguy is in STATE_ACTIVE */
+ void set_colgroup_active(CollisionGroup group);
private:
void try_activate();
+protected:
+ Physic physic;
+
+private:
State state;
- bool is_active_flag; /**< true if state was STATE_ACTIVE at the beginning of the last call to update() */
+
+ /** true if state was STATE_ACTIVE at the beginning of the last call
+ to update() */
+ bool is_active_flag;
+
Timer state_timer;
- bool on_ground_flag; /**< true if we touched something solid from above and update_on_ground_flag was called last frame */
- Vector floor_normal; /**< floor normal stored the last time when update_on_ground_flag was called and we touched something solid from above */
- CollisionGroup colgroup_active; /**< CollisionGroup the badguy should be in while active */
+ /** true if we touched something solid from above and
+ update_on_ground_flag was called last frame */
+ bool on_ground_flag;
+
+ /** floor normal stored the last time when update_on_ground_flag was
+ called and we touched something solid from above */
+ Vector floor_normal;
+
+ /** CollisionGroup the badguy should be in while active */
+ CollisionGroup colgroup_active;
+
+private:
+ BadGuy(const BadGuy&);
+ BadGuy& operator=(const BadGuy&);
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "bomb.hpp"
-#include "random_generator.hpp"
-#include "object/explosion.hpp"
#include "audio/sound_manager.hpp"
-#include "lisp/writer.hpp"
-#include "sprite/sprite.hpp"
+#include "badguy/bomb.hpp"
+#include "object/explosion.hpp"
#include "object/player.hpp"
-#include "sector.hpp"
-
-Bomb::Bomb(const Vector& pos, Direction dir, std::string custom_sprite /*= "images/creatures/mr_bomb/mr_bomb.sprite"*/ )
- : BadGuy( pos, dir, custom_sprite ), grabbed(false), grabber(NULL)
+#include "sprite/sprite.hpp"
+#include "supertux/sector.hpp"
+
+Bomb::Bomb(const Vector& pos, Direction dir, std::string custom_sprite /*= "images/creatures/mr_bomb/mr_bomb.sprite"*/ ) :
+ BadGuy( pos, dir, custom_sprite ),
+ state(),
+ grabbed(false),
+ grabber(NULL),
+ ticking()
{
state = STATE_TICKING;
set_action(dir == LEFT ? "ticking-left" : "ticking-right", 1);
ticking->play();
}
-Bomb::Bomb(const Bomb& other)
- : BadGuy(other), Portable(other), state(other.state)
-{
- if (state == STATE_TICKING) {
- ticking.reset(sound_manager->create_sound_source("sounds/fizz.wav"));
- ticking->set_position(get_pos());
- ticking->set_looping(true);
- ticking->set_gain(2.0);
- ticking->set_reference_distance(32);
- ticking->play();
- }
-}
-
-void
-Bomb::write(lisp::Writer& )
-{
- // bombs are only temporarily so don't write them out...
-}
-
void
Bomb::collision_solid(const CollisionHit& hit)
{
if(hit.bottom)
physic.set_velocity_y(0);
- update_on_ground_flag(hit);
+ update_on_ground_flag(hit);
}
HitResponse
Player* player = dynamic_cast<Player*>(grabber);
if (player)
- player->stop_grabbing();
+ player->stop_grabbing();
}
if(is_valid()) {
grabbed = false;
}
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __BOMB_H__
-#define __BOMB_H__
+#ifndef HEADER_SUPERTUX_BADGUY_BOMB_HPP
+#define HEADER_SUPERTUX_BADGUY_BOMB_HPP
-#include "badguy.hpp"
-#include "object/portable.hpp"
#include "audio/sound_source.hpp"
+#include "badguy/badguy.hpp"
+#include "object/portable.hpp"
-class Bomb : public BadGuy, public Portable
+class Bomb : public BadGuy,
+ public Portable
{
public:
Bomb(const Vector& pos, Direction dir, std::string custom_sprite = "images/creatures/mr_bomb/bomb.sprite" );
- Bomb(const Bomb& bomb);
- void write(lisp::Writer& writer);
void collision_solid(const CollisionHit& hit);
HitResponse collision_player(Player& player, const CollisionHit& hit);
HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
MovingObject* grabber;
std::auto_ptr<SoundSource> ticking;
+
+private:
+ Bomb(const Bomb&);
+ Bomb& operator=(const Bomb&);
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "bouncing_snowball.hpp"
+#include "badguy/bouncing_snowball.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
#include "sprite/sprite.hpp"
+#include "supertux/object_factory.hpp"
static const float JUMPSPEED = -450;
static const float WALKSPEED = 80;
-BouncingSnowball::BouncingSnowball(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/bouncing_snowball/bouncing_snowball.sprite")
+BouncingSnowball::BouncingSnowball(const Reader& reader)
+ : BadGuy(reader, "images/creatures/bouncing_snowball/bouncing_snowball.sprite")
{
}
}
void
-BouncingSnowball::write(lisp::Writer& writer)
-{
- writer.start_list("bouncingsnowball");
-
- writer.write("x", start_position.x);
- writer.write("y", start_position.y);
-
- writer.end_list("bouncingsnowball");
-}
-
-void
BouncingSnowball::initialize()
{
physic.set_velocity_x(dir == LEFT ? -WALKSPEED : WALKSPEED);
return CONTINUE;
}
-IMPLEMENT_FACTORY(BouncingSnowball, "bouncingsnowball")
+IMPLEMENT_FACTORY(BouncingSnowball, "bouncingsnowball");
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __BOUNCING_SNOWBALL_H__
-#define __BOUNCING_SNOWBALL_H__
+#ifndef HEADER_SUPERTUX_BADGUY_BOUNCING_SNOWBALL_HPP
+#define HEADER_SUPERTUX_BADGUY_BOUNCING_SNOWBALL_HPP
-#include "badguy.hpp"
+#include "badguy/badguy.hpp"
class BouncingSnowball : public BadGuy
{
public:
- BouncingSnowball(const lisp::Lisp& reader);
+ BouncingSnowball(const Reader& reader);
BouncingSnowball(const Vector& pos, Direction d);
void initialize();
- void write(lisp::Writer& writer);
void collision_solid(const CollisionHit& hit);
HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
- virtual BouncingSnowball* clone() const { return new BouncingSnowball(*this); }
-
protected:
bool collision_squished(GameObject& object);
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2008 Wolfgang Becker <uafr@gmx.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "captainsnowball.hpp"
+#include "badguy/captainsnowball.hpp"
-#include "object_factory.hpp"
-#include "sector.hpp"
#include "sprite/sprite.hpp"
+#include "supertux/object_factory.hpp"
+#include "supertux/sector.hpp"
namespace{
static const float WALK_SPEED = 100;
static const float BOARDING_SPEED = 200;
}
-
-CaptainSnowball::CaptainSnowball(const lisp::Lisp& reader)
- : WalkingBadguy(reader, "images/creatures/snowball/cpt-snowball.sprite", "left", "right")
+CaptainSnowball::CaptainSnowball(const Reader& reader)
+ : WalkingBadguy(reader, "images/creatures/snowball/cpt-snowball.sprite", "left", "right")
{
walk_speed = BOARDING_SPEED;
max_drop_height = -1;
}
CaptainSnowball::CaptainSnowball(const Vector& pos, Direction d)
- : WalkingBadguy(pos, d, "images/creatures/snowball/cpt-snowball.sprite", "left", "right")
+ : WalkingBadguy(pos, d, "images/creatures/snowball/cpt-snowball.sprite", "left", "right")
{
// Created during game eg. by dispencer. Board the enemy!
walk_speed = BOARDING_SPEED;
return true;
}
-IMPLEMENT_FACTORY(CaptainSnowball, "captainsnowball")
+IMPLEMENT_FACTORY(CaptainSnowball, "captainsnowball");
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2008 Wolfgang Becker <uafr@gmx.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __CAPTAINSNOWBALL_H__
-#define __CAPTAINSNOWBALL_H__
+#ifndef HEADER_SUPERTUX_BADGUY_CAPTAINSNOWBALL_HPP
+#define HEADER_SUPERTUX_BADGUY_CAPTAINSNOWBALL_HPP
-#include "walking_badguy.hpp"
+#include "badguy/walking_badguy.hpp"
class CaptainSnowball : public WalkingBadguy
{
public:
- CaptainSnowball(const lisp::Lisp& reader);
+ CaptainSnowball(const Reader& reader);
CaptainSnowball(const Vector& pos, Direction d);
- virtual CaptainSnowball* clone() const { return new CaptainSnowball(*this); }
virtual void active_update(float elapsed_time);
void collision_solid(const CollisionHit& hit);
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux - Crystallo
// Copyright (C) 2008 Wolfgang Becker <uafr@gmx.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "crystallo.hpp"
+#include "badguy/crystallo.hpp"
-#include "object_factory.hpp"
-#include "lisp/lisp.hpp"
#include "sprite/sprite.hpp"
+#include "supertux/object_factory.hpp"
-Crystallo::Crystallo(const lisp::Lisp& reader)
- : WalkingBadguy(reader, "images/creatures/crystallo/crystallo.sprite", "left", "right")
+Crystallo::Crystallo(const Reader& reader) :
+ WalkingBadguy(reader, "images/creatures/crystallo/crystallo.sprite", "left", "right"),
+ radius()
{
walk_speed = 80;
max_drop_height = 16;
reader.get("radius", radius);
}
-Crystallo::Crystallo(const Vector& pos, Direction d)
- : WalkingBadguy(pos, d, "images/creatures/crystallo/crystallo.sprite", "left", "right")
+Crystallo::Crystallo(const Vector& pos, Direction d) :
+ WalkingBadguy(pos, d, "images/creatures/crystallo/crystallo.sprite", "left", "right"),
+ radius()
{
walk_speed = 80;
max_drop_height = 16;
return true;
}
-IMPLEMENT_FACTORY(Crystallo, "crystallo")
+IMPLEMENT_FACTORY(Crystallo, "crystallo");
+
+/* EOF */
-// $Id$
-//
// SuperTux - Crystallo
// Copyright (C) 2008 Wolfgang Becker <uafr@gmx.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __CRYSTALLO_H__
-#define __CRSYTALLO_H__
+#ifndef HEADER_SUPERTUX_BADGUY_CRYSTALLO_HPP
+#define HEADER_SUPERTUX_BADGUY_CRYSTALLO_HPP
-#include "walking_badguy.hpp"
+#include "badguy/walking_badguy.hpp"
/*
* Basic badguy, patrols around a fixed position.
class Crystallo : public WalkingBadguy
{
public:
- Crystallo(const lisp::Lisp& reader);
+ Crystallo(const Reader& reader);
Crystallo(const Vector& pos, Direction d);
- virtual Crystallo* clone() const { return new Crystallo(*this); }
-
void active_update(float elapsed_time);
protected:
};
#endif
+
+/* EOF */
-// $Id$
-//
// Dart - Your average poison dart
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "dart.hpp"
+#include "badguy/dart.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
#include "audio/sound_manager.hpp"
#include "audio/sound_source.hpp"
#include "sprite/sprite.hpp"
+#include "supertux/object_factory.hpp"
namespace {
- const float SPEED = 200;
+const float SPEED = 200;
}
static const std::string SOUNDFILE = "sounds/flame.wav";
-Dart::Dart(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/dart/dart.sprite"), parent(0)
+Dart::Dart(const Reader& reader) :
+ BadGuy(reader, "images/creatures/dart/dart.sprite"),
+ parent(0),
+ sound_source()
{
physic.enable_gravity(false);
countMe = false;
sound_manager->preload("sounds/stomp.wav");
}
-Dart::Dart(const Vector& pos, Direction d, const BadGuy* parent = 0)
- : BadGuy(pos, d, "images/creatures/dart/dart.sprite"), parent(parent)
+Dart::Dart(const Vector& pos, Direction d, const BadGuy* parent = 0) :
+ BadGuy(pos, d, "images/creatures/dart/dart.sprite"),
+ parent(parent),
+ sound_source()
{
physic.enable_gravity(false);
countMe = false;
sound_manager->preload("sounds/stomp.wav");
}
-Dart::Dart(const Dart& other)
- : BadGuy(other), parent(other.parent)
-{
- sound_manager->preload(SOUNDFILE);
- sound_manager->preload("sounds/darthit.wav");
- sound_manager->preload("sounds/stomp.wav");
-}
-
Dart::~Dart()
{
}
}
void
-Dart::write(lisp::Writer& writer)
-{
- writer.start_list("dart");
- writer.write("x", start_position.x);
- writer.write("y", start_position.y);
- writer.end_list("dart");
-}
-
-void
Dart::initialize()
{
physic.set_velocity_x(dir == LEFT ? -::SPEED : ::SPEED);
return BadGuy::collision_player(player, hit);
}
-IMPLEMENT_FACTORY(Dart, "dart")
+IMPLEMENT_FACTORY(Dart, "dart");
+
+/* EOF */
-// $Id$
-//
// Dart - Your average poison dart
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __DART_H__
-#define __DART_H__
+#ifndef HEADER_SUPERTUX_BADGUY_DART_HPP
+#define HEADER_SUPERTUX_BADGUY_DART_HPP
-#include "badguy.hpp"
+#include "badguy/badguy.hpp"
class SoundSource;
class Dart : public BadGuy
{
public:
- Dart(const lisp::Lisp& reader);
+ Dart(const Reader& reader);
Dart(const Vector& pos, Direction d, const BadGuy* parent);
- Dart(const Dart& dart);
~Dart();
void initialize();
void activate();
void deactivate();
- void write(lisp::Writer& writer);
-
+
void active_update(float elapsed_time);
void collision_solid(const CollisionHit& hit);
HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
HitResponse collision_player(Player& player, const CollisionHit& hit);
- virtual Dart* clone() const { return new Dart(*this); }
-
virtual bool updatePointers(const GameObject* from_object, GameObject* to_object);
protected:
const BadGuy* parent; /**< collisions with this BadGuy will be ignored */
std::auto_ptr<SoundSource> sound_source; /**< SoundSource for ambient sound */
+
+private:
+ Dart(const Dart&);
+ Dart& operator=(const Dart&);
};
#endif
+
+/* EOF */
-// $Id$
-//
// DartTrap - Shoots a Dart at regular intervals
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "darttrap.hpp"
-#include "dart.hpp"
+#include "badguy/dart.hpp"
+#include "badguy/darttrap.hpp"
-#include "object_factory.hpp"
#include "audio/sound_manager.hpp"
-#include "lisp/writer.hpp"
-#include "sector.hpp"
-#include "lisp/lisp.hpp"
#include "sprite/sprite.hpp"
+#include "supertux/object_factory.hpp"
+#include "supertux/sector.hpp"
namespace {
- const float MUZZLE_Y = 25; /**< [px] muzzle y-offset from top */
+const float MUZZLE_Y = 25; /**< [px] muzzle y-offset from top */
}
-DartTrap::DartTrap(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/darttrap/darttrap.sprite", LAYER_TILES-1), initial_delay(0), fire_delay(2), ammo(-1), state(IDLE)
+DartTrap::DartTrap(const Reader& reader) :
+ BadGuy(reader, "images/creatures/darttrap/darttrap.sprite", LAYER_TILES-1),
+ initial_delay(0),
+ fire_delay(2),
+ ammo(-1),
+ state(IDLE),
+ fire_timer()
{
reader.get("initial-delay", initial_delay);
reader.get("fire-delay", fire_delay);
}
void
-DartTrap::write(lisp::Writer& writer)
-{
- writer.start_list("darttrap");
- writer.write("x", start_position.x);
- writer.write("y", start_position.y);
- writer.write("initial-delay", initial_delay);
- writer.write("fire-delay", fire_delay);
- writer.write("ammo", ammo);
- writer.end_list("darttrap");
-}
-
-void
DartTrap::initialize()
{
sprite->set_action(dir == LEFT ? "idle-left" : "idle-right");
sprite->set_action(dir == LEFT ? "idle-left" : "idle-right");
}
-IMPLEMENT_FACTORY(DartTrap, "darttrap")
+IMPLEMENT_FACTORY(DartTrap, "darttrap");
+
+/* EOF */
-// $Id$
-//
// DartTrap - Shoots a Dart at regular intervals
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#ifndef __DARTTRAP_H__
-#define __DARTTRAP_H__
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "badguy.hpp"
-#include "timer.hpp"
+#ifndef HEADER_SUPERTUX_BADGUY_DARTTRAP_HPP
+#define HEADER_SUPERTUX_BADGUY_DARTTRAP_HPP
/**
* Badguy "DartTrap" - Shoots a Dart at regular intervals
class DartTrap : public BadGuy
{
public:
- DartTrap(const lisp::Lisp& reader);
+ DartTrap(const Reader& reader);
void initialize();
void activate();
- void write(lisp::Writer& writer);
void active_update(float elapsed_time);
HitResponse collision_player(Player& player, const CollisionHit& hit);
- virtual DartTrap* clone() const { return new DartTrap(*this); }
-
protected:
enum State {
IDLE, LOADING
void load(); /**< load a shot */
void fire(); /**< fire a shot */
+private:
float initial_delay; /**< time to wait before firing first shot */
float fire_delay; /**< reload time */
int ammo; /**< ammo left (-1 means unlimited) */
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "dispenser.hpp"
+#include "badguy/dispenser.hpp"
-#include "object/bullet.hpp"
-#include "random_generator.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
#include "audio/sound_manager.hpp"
-#include "sector.hpp"
+#include "math/random_generator.hpp"
+#include "object/bullet.hpp"
#include "object/player.hpp"
-#include "log.hpp"
-
-#include <stdexcept>
-
-Dispenser::Dispenser(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/dispenser/dispenser.sprite")
+#include "supertux/object_factory.hpp"
+#include "supertux/sector.hpp"
+
+Dispenser::Dispenser(const Reader& reader) :
+ BadGuy(reader, "images/creatures/dispenser/dispenser.sprite"),
+ cycle(),
+ badguys(),
+ next_badguy(),
+ dispense_timer(),
+ autotarget(),
+ swivel(),
+ broken(),
+ random(),
+ type()
{
set_colgroup_active(COLGROUP_MOVING_STATIC);
sound_manager->preload("sounds/squish.wav");
}
void
-Dispenser::write(lisp::Writer& writer)
-{
- writer.start_list("dispenser");
-
- writer.write("x", start_position.x);
- writer.write("y", start_position.y);
- writer.write("cycle", cycle);
- writer.write("random", random);
- writer.write("type", type);
- writer.write("badguy", badguys);
-
- writer.end_list("dispenser");
-}
-
-void
Dispenser::activate()
{
- if( broken ){
- return;
- }
- if( autotarget && !swivel ){ // auto cannon sprite might be wrong
- Player* player = this->get_nearest_player();
- if( player ){
- dir = (player->get_pos().x > get_pos().x) ? RIGHT : LEFT;
- sprite->set_action(dir == LEFT ? "working-left" : "working-right");
- }
- }
- dispense_timer.start(cycle, true);
- launch_badguy();
+ if( broken ){
+ return;
+ }
+ if( autotarget && !swivel ){ // auto cannon sprite might be wrong
+ Player* player = this->get_nearest_player();
+ if( player ){
+ dir = (player->get_pos().x > get_pos().x) ? RIGHT : LEFT;
+ sprite->set_action(dir == LEFT ? "working-left" : "working-right");
+ }
+ }
+ dispense_timer.start(cycle, true);
+ launch_badguy();
}
void
Dispenser::deactivate()
{
- dispense_timer.stop();
+ dispense_timer.stop();
}
//TODO: Add launching velocity to certain badguys
return FORCE_MOVE;
}
-
void
Dispenser::active_update(float )
{
{
return true;
}
-IMPLEMENT_FACTORY(Dispenser, "dispenser")
+IMPLEMENT_FACTORY(Dispenser, "dispenser");
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __DISPENSER_H__
-#define __DISPENSER_H__
+#ifndef HEADER_SUPERTUX_BADGUY_DISPENSER_HPP
+#define HEADER_SUPERTUX_BADGUY_DISPENSER_HPP
-#include "badguy.hpp"
-#include "timer.hpp"
+#include "badguy/badguy.hpp"
class Dispenser : public BadGuy
{
public:
- Dispenser(const lisp::Lisp& reader);
+ Dispenser(const Reader& reader);
void activate();
void deactivate();
- void write(lisp::Writer& writer);
void active_update(float elapsed_time);
void freeze();
void unfreeze();
bool is_freezable() const;
- virtual Dispenser* clone() const { return new Dispenser(*this); }
-
protected:
bool collision_squished(GameObject& object);
HitResponse collision(GameObject& other, const CollisionHit& hit);
void launch_badguy();
+
+private:
float cycle;
std::vector<std::string> badguys;
unsigned int next_badguy;
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "fish.hpp"
+#include "badguy/fish.hpp"
-#include "tile.hpp"
-#include "object/tilemap.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
#include "sprite/sprite.hpp"
-#include "log.hpp"
+#include "supertux/object_factory.hpp"
+#include "supertux/tile.hpp"
static const float FISH_JUMP_POWER = -600;
static const float FISH_WAIT_TIME = 1;
-Fish::Fish(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/fish/fish.sprite", LAYER_TILES-1), stop_y(0)
+Fish::Fish(const Reader& reader) :
+ BadGuy(reader, "images/creatures/fish/fish.sprite", LAYER_TILES-1),
+ waiting(),
+ stop_y(0)
{
physic.enable_gravity(true);
}
-Fish::Fish(const Vector& pos)
- : BadGuy(pos, "images/creatures/fish/fish.sprite", LAYER_TILES-1), stop_y(0)
+Fish::Fish(const Vector& pos) :
+ BadGuy(pos, "images/creatures/fish/fish.sprite", LAYER_TILES-1),
+ waiting(),
+ stop_y(0)
{
physic.enable_gravity(true);
}
void
-Fish::write(lisp::Writer& writer)
-{
- writer.start_list("fish");
-
- writer.write("x", start_position.x);
- writer.write("y", start_position.y);
-
- writer.end_list("fish");
-}
-
-void
Fish::collision_solid(const CollisionHit& chit)
{
hit(chit);
return true;
}
-IMPLEMENT_FACTORY(Fish, "fish")
+IMPLEMENT_FACTORY(Fish, "fish");
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __FISH_H__
-#define __FISH_H__
+#ifndef HEADER_SUPERTUX_BADGUY_FISH_HPP
+#define HEADER_SUPERTUX_BADGUY_FISH_HPP
-#include "badguy.hpp"
+#include "badguy/badguy.hpp"
class Fish : public BadGuy
{
public:
- Fish(const lisp::Lisp& );
+ Fish(const Reader& );
Fish(const Vector& pos);
void draw(DrawingContext& context);
HitResponse collision_badguy(BadGuy& , const CollisionHit& );
void collision_tile(uint32_t tile_attributes);
- void write(lisp::Writer& );
void active_update(float);
void freeze();
void unfreeze();
bool is_freezable() const;
- virtual Fish* clone() const { return new Fish(*this); }
-
private:
HitResponse hit(const CollisionHit& );
void start_waiting();
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "flame.hpp"
+#include "badguy/flame.hpp"
-#include "log.hpp"
-#include "lisp/writer.hpp"
-#include "lisp/lisp.hpp"
-#include "object_factory.hpp"
#include "audio/sound_manager.hpp"
+#include "lisp/lisp.hpp"
+#include "supertux/object_factory.hpp"
#include <math.h>
static const std::string SOUNDFILE = "sounds/flame.wav";
-Flame::Flame(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/flame/flame.sprite", LAYER_FLOATINGOBJECTS), angle(0), radius(100), speed(2)
+Flame::Flame(const Reader& reader) :
+ BadGuy(reader, "images/creatures/flame/flame.sprite", LAYER_FLOATINGOBJECTS),
+ angle(0),
+ radius(100),
+ speed(2),
+ sound_source()
{
reader.get("radius", radius);
reader.get("speed", speed);
}
void
-Flame::write(lisp::Writer& writer)
-{
- writer.start_list("flame");
-
- writer.write("x", start_position.x);
- writer.write("y", start_position.y);
- writer.write("radius", radius);
- writer.write("speed", speed);
-
- writer.end_list("flame");
-}
-
-void
Flame::active_update(float elapsed_time)
{
angle = fmodf(angle + elapsed_time * speed, (float) (2*M_PI));
{
}
-IMPLEMENT_FACTORY(Flame, "flame")
+IMPLEMENT_FACTORY(Flame, "flame");
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#ifndef __FLAME_H__
-#define __FLAME_H__
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_BADGUY_FLAME_HPP
+#define HEADER_SUPERTUX_BADGUY_FLAME_HPP
-#include "badguy.hpp"
+#include "badguy/badguy.hpp"
#include "audio/sound_source.hpp"
class Flame : public BadGuy
{
public:
- Flame(const lisp::Lisp& reader);
+ Flame(const Reader& reader);
Flame(const Flame& flame);
void activate();
void deactivate();
- void write(lisp::Writer& write);
void active_update(float elapsed_time);
void kill_fall();
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
-
-#include <stdio.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "flyingsnowball.hpp"
+#include "badguy/flyingsnowball.hpp"
-#include "random_generator.hpp"
+#include "math/random_generator.hpp"
#include "object/sprite_particle.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
-#include "sector.hpp"
+#include "object/player.hpp"
+#include "supertux/object_factory.hpp"
+#include "supertux/sector.hpp"
namespace {
- const float PUFF_INTERVAL_MIN = 4.0f; /**< spawn new puff of smoke at most that often */
- const float PUFF_INTERVAL_MAX = 8.0f; /**< spawn new puff of smoke at least that often */
+const float PUFF_INTERVAL_MIN = 4.0f; /**< spawn new puff of smoke at most that often */
+const float PUFF_INTERVAL_MAX = 8.0f; /**< spawn new puff of smoke at least that often */
}
-FlyingSnowBall::FlyingSnowBall(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/flying_snowball/flying_snowball.sprite")
+FlyingSnowBall::FlyingSnowBall(const Reader& reader) :
+ BadGuy(reader, "images/creatures/flying_snowball/flying_snowball.sprite"),
+ normal_propeller_speed(),
+ puff_timer()
{
physic.enable_gravity(true);
}
-FlyingSnowBall::FlyingSnowBall(const Vector& pos)
- : BadGuy(pos, "images/creatures/flying_snowball/flying_snowball.sprite")
+FlyingSnowBall::FlyingSnowBall(const Vector& pos) :
+ BadGuy(pos, "images/creatures/flying_snowball/flying_snowball.sprite"),
+ normal_propeller_speed(),
+ puff_timer()
{
physic.enable_gravity(true);
}
void
-FlyingSnowBall::write(lisp::Writer& writer)
-{
- writer.start_list("flyingsnowball");
-
- writer.write("x", start_position.x);
- writer.write("y", start_position.y);
-
- writer.end_list("flyingsnowball");
-}
-
-void
FlyingSnowBall::initialize()
{
sprite->set_action(dir == LEFT ? "left" : "right");
FlyingSnowBall::active_update(float elapsed_time)
{
- const float grav = physic.get_gravity()*100;
+ const float grav = Sector::current()->get_gravity() * 100.0f;
if (get_pos().y > start_position.y + 2*32) {
// Flying too low - increased propeller speed
// Flying too high - decreased propeller speed
physic.set_acceleration_y(-grav*0.8);
- physic.set_velocity_y(physic.get_velocity_y() * 0.99);
+ physic.set_velocity_y(physic.get_velocity_y() * 0.99f);
} else {
}
}
-IMPLEMENT_FACTORY(FlyingSnowBall, "flyingsnowball")
+IMPLEMENT_FACTORY(FlyingSnowBall, "flyingsnowball");
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __FLYINGSNOWBALL_H__
-#define __FLYINGSNOWBALL_H__
+#ifndef HEADER_SUPERTUX_BADGUY_FLYINGSNOWBALL_HPP
+#define HEADER_SUPERTUX_BADGUY_FLYINGSNOWBALL_HPP
-#include "badguy.hpp"
+#include "badguy/badguy.hpp"
class FlyingSnowBall : public BadGuy
{
public:
- FlyingSnowBall(const lisp::Lisp& reader);
+ FlyingSnowBall(const Reader& reader);
FlyingSnowBall(const Vector& pos);
void initialize();
void activate();
- void write(lisp::Writer& writer);
void active_update(float elapsed_time);
void collision_solid(const CollisionHit& hit);
- virtual FlyingSnowBall* clone() const { return new FlyingSnowBall(*this); }
-
protected:
bool collision_squished(GameObject& object);
private:
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux - Boss "GhostTree"
// Copyright (C) 2007 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "ghosttree.hpp"
+#include "badguy/ghosttree.hpp"
-#include "treewillowisp.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "sprite/sprite.hpp"
-#include "root.hpp"
-#include "random_generator.hpp"
-#include "object/lantern.hpp"
-#include "object_factory.hpp"
#include "audio/sound_manager.hpp"
-#include "sector.hpp"
+#include "badguy/root.hpp"
+#include "badguy/treewillowisp.hpp"
+#include "math/random_generator.hpp"
+#include "object/lantern.hpp"
#include "object/player.hpp"
-#include "video/drawing_context.hpp"
+#include "sprite/sprite.hpp"
+#include "sprite/sprite_manager.hpp"
+#include "supertux/object_factory.hpp"
+#include "supertux/sector.hpp"
-#include <math.h>
#include <algorithm>
+#include <math.h>
static const size_t WILLOWISP_COUNT = 10;
static const float ROOT_TOP_OFFSET = 64;
static const Vector SUCK_TARGET_OFFSET = Vector(-16,-16);
static const float SUCK_TARGET_SPREAD = 8;
-GhostTree::GhostTree(const lisp::Lisp& lisp)
- : BadGuy(lisp, "images/creatures/ghosttree/ghosttree.sprite",
- LAYER_OBJECTS - 10), mystate(STATE_IDLE),
- willo_spawn_y(0), willo_radius(200), willo_speed(1.8f), willo_color(0),
- treecolor(0), suck_lantern(0)
+GhostTree::GhostTree(const Reader& lisp) :
+ BadGuy(lisp, "images/creatures/ghosttree/ghosttree.sprite", LAYER_OBJECTS - 10),
+ mystate(STATE_IDLE),
+ willowisp_timer(),
+ willo_spawn_y(0),
+ willo_radius(200),
+ willo_speed(1.8f),
+ willo_color(0),
+ glow_sprite(),
+ colorchange_timer(),
+ suck_timer(),
+ root_timer(),
+ treecolor(0),
+ suck_lantern_color(),
+ suck_lantern(0),
+ willowisps()
{
- glow_sprite.reset(sprite_manager->create("images/creatures/ghosttree/ghosttree-glow.sprite"));
+ glow_sprite = sprite_manager->create("images/creatures/ghosttree/ghosttree-glow.sprite");
set_colgroup_active(COLGROUP_TOUCHABLE);
sound_manager->preload("sounds/tree_howling.ogg");
sound_manager->preload("sounds/tree_suck.ogg");
if(willowisps.size() < WILLOWISP_COUNT) {
Vector pos = Vector(bbox.get_width() / 2, bbox.get_height() / 2 + willo_spawn_y + WILLOWISP_TOP_OFFSET);
TreeWillOWisp *willowisp
- = new TreeWillOWisp(this, pos, 200 + willo_radius, willo_speed);
+ = new TreeWillOWisp(this, pos, 200 + willo_radius, willo_speed);
Sector::current()->add_object(willowisp);
willowisps.push_back(willowisp);
IMPLEMENT_FACTORY(GhostTree, "ghosttree");
+/* EOF */
-// $Id$
-//
// SuperTux - Boss "GhostTree"
// Copyright (C) 2007 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#ifndef __GHOSTTREE_H__
-#define __GHOSTTREE_H__
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_BADGUY_GHOSTTREE_HPP
+#define HEADER_SUPERTUX_BADGUY_GHOSTTREE_HPP
-#include <vector>
-#include "badguy.hpp"
+#include "badguy/badguy.hpp"
class TreeWillOWisp;
class Lantern;
class GhostTree : public BadGuy
{
public:
- GhostTree(const lisp::Lisp& lisp);
+ GhostTree(const Reader& lisp);
~GhostTree();
virtual bool is_flammable() const { return false; }
bool is_color_deadly(Color color) const;
void spawn_lantern();
+
+private:
+ GhostTree(const GhostTree&);
+ GhostTree& operator=(const GhostTree&);
};
#endif
+/* EOF */
-// $Id$
-//
// SuperTux - Badguy "Igel"
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "igel.hpp"
-#include "object/block.hpp"
-#include "sector.hpp"
+#include "badguy/igel.hpp"
#include "object/bullet.hpp"
+#include "supertux/sector.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
+#include "supertux/object_factory.hpp"
namespace {
- const float WALKSPEED = 80; /**< speed at which we walk around */
- const float TURN_RECOVER_TIME = 0.5; /**< seconds before we will again turn around when shot at */
- const float RANGE_OF_VISION = 256; /**< range in px at which we can see bullets */
-}
-Igel::Igel(const lisp::Lisp& reader)
- : WalkingBadguy(reader, "images/creatures/igel/igel.sprite", "walking-left", "walking-right")
+const float WALKSPEED = 80; /**< speed at which we walk around */
+const float TURN_RECOVER_TIME = 0.5; /**< seconds before we will again turn around when shot at */
+const float RANGE_OF_VISION = 256; /**< range in px at which we can see bullets */
+
+} // namespace
+
+Igel::Igel(const Reader& reader) :
+ WalkingBadguy(reader, "images/creatures/igel/igel.sprite", "walking-left", "walking-right"),
+ turn_recover_timer()
{
walk_speed = WALKSPEED;
max_drop_height = 16;
}
-Igel::Igel(const Vector& pos, Direction d)
- : WalkingBadguy(pos, d, "images/creatures/igel/igel.sprite", "walking-left", "walking-right")
+Igel::Igel(const Vector& pos, Direction d) :
+ WalkingBadguy(pos, d, "images/creatures/igel/igel.sprite", "walking-left", "walking-right"),
+ turn_recover_timer()
{
walk_speed = WALKSPEED;
max_drop_height = 16;
}
void
-Igel::write(lisp::Writer& writer)
-{
- writer.start_list("igel");
- WalkingBadguy::write(writer);
- writer.end_list("igel");
-}
-
-void
Igel::be_normal()
{
initialize();
return false;
}
-IMPLEMENT_FACTORY(Igel, "igel")
+IMPLEMENT_FACTORY(Igel, "igel");
+
+/* EOF */
-// $Id$
-//
// SuperTux - Badguy "Igel"
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __IGEL_H__
-#define __IGEL_H__
+#ifndef HEADER_SUPERTUX_BADGUY_IGEL_HPP
+#define HEADER_SUPERTUX_BADGUY_IGEL_HPP
-#include "walking_badguy.hpp"
-#include "moving_object.hpp"
+#include "badguy/walking_badguy.hpp"
/**
* Badguy "Igel" - a hedgehog that can absorb bullets
class Igel : public WalkingBadguy
{
public:
- Igel(const lisp::Lisp& reader);
+ Igel(const Reader& reader);
Igel(const Vector& pos, Direction d);
- void write(lisp::Writer& writer);
HitResponse collision_bullet(Bullet& bullet, const CollisionHit& hit);
void active_update(float elapsed_time);
- virtual Igel* clone() const { return new Igel(*this); }
-
protected:
bool collision_squished(GameObject& object);
void be_normal(); /**< switch to state STATE_NORMAL */
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "jumpy.hpp"
+#include "badguy/jumpy.hpp"
-#include "lisp/writer.hpp"
-#include "sprite/sprite.hpp"
-#include "object_factory.hpp"
#include "object/player.hpp"
+#include "sprite/sprite.hpp"
+#include "supertux/object_factory.hpp"
static const float JUMPSPEED=-600;
static const float JUMPY_MID_TOLERANCE=4;
static const float JUMPY_LOW_TOLERANCE=2;
-Jumpy::Jumpy(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/snowjumpy/snowjumpy.sprite"), groundhit_pos_set(false)
+Jumpy::Jumpy(const Reader& reader) :
+ BadGuy(reader, "images/creatures/snowjumpy/snowjumpy.sprite"),
+ pos_groundhit(),
+ groundhit_pos_set(false)
{
// TODO create a nice sound for this...
//sound_manager->preload("sounds/skid.wav");
}
void
-Jumpy::write(lisp::Writer& writer)
-{
- writer.start_list("jumpy");
-
- writer.write("x", start_position.x);
- writer.write("y", start_position.y);
-
- writer.end_list("jumpy");
-}
-
-void
Jumpy::collision_solid(const CollisionHit& chit)
{
hit(chit);
if ( get_pos().y < (pos_groundhit.y - JUMPY_MID_TOLERANCE ) )
sprite->set_action(dir == LEFT ? "left-up" : "right-up");
else if ( get_pos().y >= (pos_groundhit.y - JUMPY_MID_TOLERANCE) &&
- get_pos().y < (pos_groundhit.y - JUMPY_LOW_TOLERANCE) )
+ get_pos().y < (pos_groundhit.y - JUMPY_LOW_TOLERANCE) )
sprite->set_action(dir == LEFT ? "left-middle" : "right-middle");
else
sprite->set_action(dir == LEFT ? "left-down" : "right-down");
return true;
}
-IMPLEMENT_FACTORY(Jumpy, "jumpy")
+IMPLEMENT_FACTORY(Jumpy, "jumpy");
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __JUMPY_H__
-#define __JUMPY_H__
+#ifndef HEADER_SUPERTUX_BADGUY_JUMPY_HPP
+#define HEADER_SUPERTUX_BADGUY_JUMPY_HPP
-#include "badguy.hpp"
+#include "badguy/badguy.hpp"
class Jumpy : public BadGuy
{
public:
- Jumpy(const lisp::Lisp& reader);
+ Jumpy(const Reader& reader);
void collision_solid(const CollisionHit& hit);
HitResponse collision_badguy(BadGuy& other, const CollisionHit& hit);
- void write(lisp::Writer& writer);
void active_update(float);
void freeze();
bool is_freezable() const;
- virtual Jumpy* clone() const { return new Jumpy(*this); }
-
private:
HitResponse hit(const CollisionHit& hit);
+
+private:
Vector pos_groundhit;
bool groundhit_pos_set;
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2008 Wolfgang Becker <uafr@gmx.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "kamikazesnowball.hpp"
+#include "badguy/kamikazesnowball.hpp"
-#include "object_factory.hpp"
#include "audio/sound_manager.hpp"
#include "sprite/sprite.hpp"
+#include "supertux/object_factory.hpp"
/*
* Kamikaze Snowball will fly in one direction until he hits something.
const std::string SPLAT_SOUND = "sounds/splat.wav";
}
-KamikazeSnowball::KamikazeSnowball(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/snowball/kamikaze-snowball.sprite")
+KamikazeSnowball::KamikazeSnowball(const Reader& reader) :
+ BadGuy(reader, "images/creatures/snowball/kamikaze-snowball.sprite")
{
sound_manager->preload(SPLAT_SOUND);
}
void
KamikazeSnowball::kill_collision()
{
- sprite->set_action(dir == LEFT ? "collision-left" : "collision-right");
- sound_manager->play(SPLAT_SOUND, get_pos());
- physic.set_velocity_x(0);
- physic.set_velocity_y(0);
- physic.enable_gravity(true);
- set_state(STATE_FALLING);
+ sprite->set_action(dir == LEFT ? "collision-left" : "collision-right");
+ sound_manager->play(SPLAT_SOUND, get_pos());
+ physic.set_velocity_x(0);
+ physic.set_velocity_y(0);
+ physic.enable_gravity(true);
+ set_state(STATE_FALLING);
- run_dead_script();
+ run_dead_script();
}
HitResponse
return response;
}
+IMPLEMENT_FACTORY(KamikazeSnowball, "kamikazesnowball");
-IMPLEMENT_FACTORY(KamikazeSnowball, "kamikazesnowball")
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2008 Wolfgang Becker <uafr@gmx.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __KAMIKAZESNOWBALL_H__
-#define __KAMIKAZESNOWBALL_H__
+#ifndef HEADER_SUPERTUX_BADGUY_KAMIKAZESNOWBALL_HPP
+#define HEADER_SUPERTUX_BADGUY_KAMIKAZESNOWBALL_HPP
-#include "badguy.hpp"
+#include "badguy/badguy.hpp"
class KamikazeSnowball : public BadGuy
{
public:
- KamikazeSnowball(const lisp::Lisp& reader);
+ KamikazeSnowball(const Reader& reader);
KamikazeSnowball(const Vector& pos, Direction d);
void initialize();
void collision_solid(const CollisionHit& hit);
- virtual KamikazeSnowball* clone() const { return new KamikazeSnowball(*this); }
-
protected:
bool collision_squished(GameObject& object);
HitResponse collision_player(Player& player, const CollisionHit& hit);
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "kugelblitz.hpp"
-#include "object/tilemap.hpp"
+#include "badguy/kugelblitz.hpp"
+#include "math/random_generator.hpp"
#include "object/camera.hpp"
-#include "tile.hpp"
-#include "random_generator.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
#include "object/player.hpp"
-#include "sector.hpp"
#include "sprite/sprite.hpp"
+#include "supertux/object_factory.hpp"
+#include "supertux/sector.hpp"
#define LIFETIME 5
#define MOVETIME 0.75
static const float X_OFFSCREEN_DISTANCE = 1600;
static const float Y_OFFSCREEN_DISTANCE = 1200;
-Kugelblitz::Kugelblitz(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/kugelblitz/kugelblitz.sprite"), groundhit_pos_set(false)
+Kugelblitz::Kugelblitz(const Reader& reader) :
+ BadGuy(reader, "images/creatures/kugelblitz/kugelblitz.sprite"),
+ pos_groundhit(),
+ groundhit_pos_set(false),
+ dying(),
+ movement_timer(),
+ lifetime(),
+ direction(),
+ state()
{
reader.get("x", start_position.x);
sprite->set_action("falling");
}
void
-Kugelblitz::write(lisp::Writer& writer)
-{
- writer.start_list("kugelblitz");
-
- writer.write("x", start_position.x);
-
- writer.end_list("kugelblitz");
-}
-
-void
Kugelblitz::initialize()
{
physic.set_velocity_y(300);
}
// hit from above?
if(player.get_movement().y - get_movement().y > 0 && player.get_bbox().p2.y <
- (get_bbox().p1.y + get_bbox().p2.y) / 2) {
+ (get_bbox().p1.y + get_bbox().p2.y) / 2) {
// if it's not is it possible to squish us, then this will hurt
if(!collision_squished(player))
player.kill(false);
- explode();
+ explode();
return FORCE_MOVE;
}
player.kill(false);
}
}
/*
- if (Sector::current()->solids->get_tile_at(get_pos())->getAttributes() == 16) {
+ if (Sector::current()->solids->get_tile_at(get_pos())->getAttributes() == 16) {
//HIT WATER
Sector::current()->add_object(new Electrifier(75,1421,1.5));
Sector::current()->add_object(new Electrifier(76,1422,1.5));
explode();
- }
- if (Sector::current()->solids->get_tile_at(get_pos())->getAttributes() == 48) {
+ }
+ if (Sector::current()->solids->get_tile_at(get_pos())->getAttributes() == 48) {
//HIT ELECTRIFIED WATER
explode();
- }
+ }
*/
}
BadGuy::active_update(elapsed_time);
set_state(STATE_ACTIVE);
activate();
} else if (start_position.x > scroll_x &&
- start_position.x < scroll_x + X_OFFSCREEN_DISTANCE &&
- start_position.y > scroll_y - Y_OFFSCREEN_DISTANCE &&
- start_position.y < scroll_y + Y_OFFSCREEN_DISTANCE) {
+ start_position.x < scroll_x + X_OFFSCREEN_DISTANCE &&
+ start_position.y > scroll_y - Y_OFFSCREEN_DISTANCE &&
+ start_position.y < scroll_y + Y_OFFSCREEN_DISTANCE) {
dir = LEFT;
set_state(STATE_ACTIVE);
activate();
} else if (start_position.x > scroll_x - X_OFFSCREEN_DISTANCE &&
- start_position.x < scroll_x + X_OFFSCREEN_DISTANCE &&
- ((start_position.y > scroll_y &&
- start_position.y < scroll_y + Y_OFFSCREEN_DISTANCE) ||
- (start_position.y > scroll_y - Y_OFFSCREEN_DISTANCE &&
- start_position.y < scroll_y))) {
+ start_position.x < scroll_x + X_OFFSCREEN_DISTANCE &&
+ ((start_position.y > scroll_y &&
+ start_position.y < scroll_y + Y_OFFSCREEN_DISTANCE) ||
+ (start_position.y > scroll_y - Y_OFFSCREEN_DISTANCE &&
+ start_position.y < scroll_y))) {
dir = start_position.x < scroll_x ? RIGHT : LEFT;
set_state(STATE_ACTIVE);
activate();
} else if(state == STATE_INIT
- && start_position.x > scroll_x - X_OFFSCREEN_DISTANCE
- && start_position.x < scroll_x + X_OFFSCREEN_DISTANCE
- && start_position.y > scroll_y - Y_OFFSCREEN_DISTANCE
- && start_position.y < scroll_y + Y_OFFSCREEN_DISTANCE) {
+ && start_position.x > scroll_x - X_OFFSCREEN_DISTANCE
+ && start_position.x < scroll_x + X_OFFSCREEN_DISTANCE
+ && start_position.y > scroll_y - Y_OFFSCREEN_DISTANCE
+ && start_position.y < scroll_y + Y_OFFSCREEN_DISTANCE) {
dir = LEFT;
set_state(STATE_ACTIVE);
activate();
}
}
-IMPLEMENT_FACTORY(Kugelblitz, "kugelblitz")
+IMPLEMENT_FACTORY(Kugelblitz, "kugelblitz");
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __KUGELBLITZ_H__
-#define __KUGELBLITZ_H__
+#ifndef HEADER_SUPERTUX_BADGUY_KUGELBLITZ_HPP
+#define HEADER_SUPERTUX_BADGUY_KUGELBLITZ_HPP
-#include "badguy.hpp"
-#include "timer.hpp"
-#include "object/electrifier.hpp"
+#include "badguy/badguy.hpp"
class Kugelblitz : public BadGuy
{
public:
- Kugelblitz(const lisp::Lisp& reader);
+ Kugelblitz(const Reader& reader);
void initialize();
HitResponse collision_badguy(BadGuy& other, const CollisionHit& hit);
void collision_solid(const CollisionHit& hit);
HitResponse collision_player(Player& player, const CollisionHit& hit);
- void write(lisp::Writer& writer);
void active_update(float);
void kill_fall();
void explode();
- virtual Kugelblitz* clone() const { return new Kugelblitz(*this); }
-
private:
void try_activate();
HitResponse hit(const CollisionHit& hit);
+
+private:
Vector pos_groundhit;
bool groundhit_pos_set;
bool dying;
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux - Mole Badguy
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
-
-#include "mole.hpp"
-#include "mole_rock.hpp"
-#include "tile.hpp"
-#include "object/tilemap.hpp"
-#include "random_generator.hpp"
-#include "log.hpp"
-#include "level.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
#include "audio/sound_manager.hpp"
-#include "sector.hpp"
+#include "badguy/mole.hpp"
+#include "badguy/mole_rock.hpp"
+#include "math/random_generator.hpp"
#include "sprite/sprite.hpp"
+#include "supertux/object_factory.hpp"
+#include "supertux/sector.hpp"
#include <math.h>
static const float THROW_INTERVAL = 1; /**< time between two thrown rocks */
static const float THROW_VELOCITY = 400; /**< initial velocity of thrown rocks */
-Mole::Mole(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/mole/mole.sprite", LAYER_TILES-1), state(PRE_THROWING)
+Mole::Mole(const Reader& reader) :
+ BadGuy(reader, "images/creatures/mole/mole.sprite", LAYER_TILES-1),
+ state(PRE_THROWING),
+ timer(),
+ throw_timer()
{
physic.enable_gravity(false);
sound_manager->preload("sounds/fall.wav");
sound_manager->preload("sounds/dartfire.wav");
}
-Mole::Mole(const Vector& pos)
- : BadGuy(pos, "images/creatures/mole/mole.sprite", LAYER_TILES-1), state(PRE_THROWING)
+Mole::Mole(const Vector& pos) :
+ BadGuy(pos, "images/creatures/mole/mole.sprite", LAYER_TILES-1),
+ state(PRE_THROWING),
+ timer(),
+ throw_timer()
{
physic.enable_gravity(false);
sound_manager->preload("sounds/fall.wav");
}
void
-Mole::write(lisp::Writer& writer)
-{
- writer.start_list("mole");
- writer.write("x", start_position.x);
- writer.write("y", start_position.y);
- writer.end_list("mole");
-}
-
-void
Mole::activate()
{
if (state != DEAD) set_state(PRE_THROWING);
state = new_state;
}
-IMPLEMENT_FACTORY(Mole, "mole")
+IMPLEMENT_FACTORY(Mole, "mole");
+
+/* EOF */
-// $Id$
-//
// SuperTux - Mole Badguy
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __MOLE_H__
-#define __MOLE_H__
+#ifndef HEADER_SUPERTUX_BADGUY_MOLE_HPP
+#define HEADER_SUPERTUX_BADGUY_MOLE_HPP
-#include "badguy.hpp"
+#include "badguy/badguy.hpp"
class Mole : public BadGuy
{
public:
- Mole(const lisp::Lisp& );
+ Mole(const Reader& );
Mole(const Vector& pos);
void kill_fall();
bool collision_squished(GameObject& object);
void activate();
- void write(lisp::Writer& );
void active_update(float);
- virtual Mole* clone() const { return new Mole(*this); }
-
private:
enum MoleState {
PRE_THROWING,
DEAD
};
- MoleState state;
- Timer timer;
- Timer throw_timer;
-
+private:
void set_state(MoleState new_state);
void throw_rock();
+private:
+ MoleState state;
+ Timer timer;
+ Timer throw_timer;
};
#endif
+
+/* EOF */
-// $Id$
-//
// MoleRock - Rock thrown by "Mole" Badguy
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "mole_rock.hpp"
+#include "badguy/mole_rock.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
#include "audio/sound_manager.hpp"
#include "sprite/sprite.hpp"
+#include "supertux/object_factory.hpp"
-MoleRock::MoleRock(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/mole/mole_rock.sprite", LAYER_TILES - 2), parent(0), initial_velocity(Vector(0, -400))
+MoleRock::MoleRock(const Reader& reader)
+ : BadGuy(reader, "images/creatures/mole/mole_rock.sprite", LAYER_TILES - 2), parent(0), initial_velocity(Vector(0, -400))
{
physic.enable_gravity(true);
countMe = false;
sound_manager->preload("sounds/stomp.wav");
}
-MoleRock::MoleRock(const Vector& pos, const Vector& velocity, const BadGuy* parent = 0)
- : BadGuy(pos, LEFT, "images/creatures/mole/mole_rock.sprite", LAYER_TILES - 2), parent(parent), initial_velocity(velocity)
+MoleRock::MoleRock(const Vector& pos, const Vector& velocity, const BadGuy* parent = 0) :
+ BadGuy(pos, LEFT, "images/creatures/mole/mole_rock.sprite", LAYER_TILES - 2),
+ parent(parent),
+ initial_velocity(velocity)
{
physic.enable_gravity(true);
countMe = false;
sound_manager->preload("sounds/stomp.wav");
}
-MoleRock::MoleRock(const MoleRock& other)
- : BadGuy(other), parent(other.parent), initial_velocity(Vector(0, -400))
-{
- sound_manager->preload("sounds/darthit.wav");
- sound_manager->preload("sounds/stomp.wav");
-}
-
MoleRock::~MoleRock()
{
}
}
void
-MoleRock::write(lisp::Writer& writer)
-{
- writer.start_list("mole_rock");
- writer.write("x", start_position.x);
- writer.write("y", start_position.y);
- writer.end_list("mole_rock");
-}
-
-void
MoleRock::initialize()
{
physic.set_velocity(initial_velocity);
return BadGuy::collision_player(player, hit);
}
-IMPLEMENT_FACTORY(MoleRock, "mole_rock")
+IMPLEMENT_FACTORY(MoleRock, "mole_rock");
+
+/* EOF */
-// $Id$
-//
// MoleRock - Rock thrown by "Mole" Badguy
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __MOLE_ROCK_H__
-#define __MOLE_ROCK_H__
+#ifndef HEADER_SUPERTUX_BADGUY_MOLE_ROCK_HPP
+#define HEADER_SUPERTUX_BADGUY_MOLE_ROCK_HPP
-#include "badguy.hpp"
+#include "badguy/badguy.hpp"
/**
* Badguy "MoleRock" - Rock thrown by "Mole" Badguy
class MoleRock : public BadGuy
{
public:
- MoleRock(const lisp::Lisp& reader);
+ MoleRock(const Reader& reader);
MoleRock(const Vector& pos, const Vector& velocity, const BadGuy* parent);
- MoleRock(const MoleRock& mole_rock);
~MoleRock();
void initialize();
void deactivate();
- void write(lisp::Writer& writer);
void active_update(float elapsed_time);
HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
HitResponse collision_player(Player& player, const CollisionHit& hit);
- virtual MoleRock* clone() const { return new MoleRock(*this); }
-
virtual bool updatePointers(const GameObject* from_object, GameObject* to_object);
protected:
const BadGuy* parent; /**< collisions with this BadGuy will be ignored */
const Vector initial_velocity; /**< velocity at time of creation */
+
+private:
+ MoleRock(const MoleRock&);
+ MoleRock& operator=(const MoleRock&);
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "mrbomb.hpp"
-#include "bomb.hpp"
-#include "object/explosion.hpp"
-#include "sprite/sprite_manager.hpp"
#include "audio/sound_manager.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
-#include "sector.hpp"
-#include "lisp/lisp.hpp"
+#include "badguy/bomb.hpp"
+#include "badguy/mrbomb.hpp"
+#include "object/explosion.hpp"
#include "sprite/sprite.hpp"
+#include "sprite/sprite_manager.hpp"
+#include "supertux/object_factory.hpp"
+#include "supertux/sector.hpp"
-MrBomb::MrBomb(const lisp::Lisp& reader)
- : WalkingBadguy(reader, "images/creatures/mr_bomb/mr_bomb.sprite", "left", "right")
+MrBomb::MrBomb(const Reader& reader) :
+ WalkingBadguy(reader, "images/creatures/mr_bomb/mr_bomb.sprite", "left", "right"),
+ grabbed()
{
walk_speed = 80;
max_drop_height = 16;
}
/* MrBomb created by a dispenser always gets default sprite atm.*/
-MrBomb::MrBomb(const Vector& pos, Direction d)
- : WalkingBadguy(pos, d, "images/creatures/mr_bomb/mr_bomb.sprite", "left", "right")
+MrBomb::MrBomb(const Vector& pos, Direction d) :
+ WalkingBadguy(pos, d, "images/creatures/mr_bomb/mr_bomb.sprite", "left", "right"),
+ grabbed()
{
walk_speed = 80;
max_drop_height = 16;
sound_manager->preload("sounds/explosion.wav");
}
-void
-MrBomb::write(lisp::Writer& writer)
-{
- writer.start_list("mrbomb");
- WalkingBadguy::write(writer);
- writer.end_list("mrbomb");
-}
-
HitResponse
MrBomb::collision(GameObject& object, const CollisionHit& hit)
{
return frozen;
}
-IMPLEMENT_FACTORY(MrBomb, "mrbomb")
+IMPLEMENT_FACTORY(MrBomb, "mrbomb");
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __MRBOMB_H__
-#define __MRBOMB_H__
+#ifndef HEADER_SUPERTUX_BADGUY_MRBOMB_HPP
+#define HEADER_SUPERTUX_BADGUY_MRBOMB_HPP
-#include "walking_badguy.hpp"
-#include "object/portable.hpp"
+#include "badguy/walking_badguy.hpp"
-class MrBomb : public WalkingBadguy, public Portable
+class MrBomb : public WalkingBadguy,
+ public Portable
{
public:
- MrBomb(const lisp::Lisp& reader);
+ MrBomb(const Reader& reader);
MrBomb(const Vector& pos, Direction d);
- void write(lisp::Writer& writer);
void kill_fall();
HitResponse collision(GameObject& object, const CollisionHit& hit);
HitResponse collision_player(Player& player, const CollisionHit& hit);
void freeze();
bool is_freezable() const;
- virtual MrBomb* clone() const { return new MrBomb(*this); }
-
protected:
bool collision_squished(GameObject& object);
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "mriceblock.hpp"
+#include "badguy/mriceblock.hpp"
-#include "object/block.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
#include "audio/sound_manager.hpp"
#include "object/player.hpp"
#include "sprite/sprite.hpp"
+#include "supertux/object_factory.hpp"
namespace {
- const float KICKSPEED = 500;
- const int MAXSQUISHES = 10;
- const float NOKICK_TIME = 0.1f;
+const float KICKSPEED = 500;
+const int MAXSQUISHES = 10;
+const float NOKICK_TIME = 0.1f;
}
-MrIceBlock::MrIceBlock(const lisp::Lisp& reader)
- : WalkingBadguy(reader, "images/creatures/mr_iceblock/mr_iceblock.sprite", "left", "right"), ice_state(ICESTATE_NORMAL), squishcount(0)
+MrIceBlock::MrIceBlock(const Reader& reader) :
+ WalkingBadguy(reader, "images/creatures/mr_iceblock/mr_iceblock.sprite", "left", "right"),
+ ice_state(ICESTATE_NORMAL),
+ nokick_timer(),
+ flat_timer(),
+ squishcount(0)
{
walk_speed = 80;
max_drop_height = 600;
sound_manager->preload("sounds/kick.wav");
}
-MrIceBlock::MrIceBlock(const Vector& pos, Direction d)
- : WalkingBadguy(pos, d, "images/creatures/mr_iceblock/mr_iceblock.sprite", "left", "right"), ice_state(ICESTATE_NORMAL), squishcount(0)
+MrIceBlock::MrIceBlock(const Vector& pos, Direction d) :
+ WalkingBadguy(pos, d, "images/creatures/mr_iceblock/mr_iceblock.sprite", "left", "right"),
+ ice_state(ICESTATE_NORMAL),
+ nokick_timer(),
+ flat_timer(),
+ squishcount(0)
{
walk_speed = 80;
max_drop_height = 600;
}
void
-MrIceBlock::write(lisp::Writer& writer)
-{
- writer.start_list("mriceblock");
- WalkingBadguy::write(writer);
- writer.end_list("mriceblock");
-}
-
-void
MrIceBlock::initialize()
{
WalkingBadguy::initialize();
bool
MrIceBlock::can_break(){
- return ice_state == ICESTATE_KICKED;
+ return ice_state == ICESTATE_KICKED;
}
void
{
switch(ice_state) {
case ICESTATE_KICKED:
- {
- BadGuy* badguy = dynamic_cast<BadGuy*>(&object);
- if (badguy) {
- badguy->kill_fall();
- break;
- }
+ {
+ BadGuy* badguy = dynamic_cast<BadGuy*>(&object);
+ if (badguy) {
+ badguy->kill_fall();
+ break;
}
+ }
- // fall through
+ // fall through
case ICESTATE_NORMAL:
- {
- Player* player = dynamic_cast<Player*>(&object);
- squishcount++;
- if ((squishcount >= MAXSQUISHES) || (player && player->does_buttjump)) {
- kill_fall();
- return true;
- }
+ {
+ Player* player = dynamic_cast<Player*>(&object);
+ squishcount++;
+ if ((squishcount >= MAXSQUISHES) || (player && player->does_buttjump)) {
+ kill_fall();
+ return true;
}
+ }
- set_state(ICESTATE_FLAT);
- nokick_timer.start(NOKICK_TIME);
- break;
+ set_state(ICESTATE_FLAT);
+ nokick_timer.start(NOKICK_TIME);
+ break;
case ICESTATE_FLAT:
- {
- MovingObject* movingobject = dynamic_cast<MovingObject*>(&object);
- if (movingobject && (movingobject->get_pos().x < get_pos().x)) {
- dir = RIGHT;
- } else {
- dir = LEFT;
- }
+ {
+ MovingObject* movingobject = dynamic_cast<MovingObject*>(&object);
+ if (movingobject && (movingobject->get_pos().x < get_pos().x)) {
+ dir = RIGHT;
+ } else {
+ dir = LEFT;
}
- if (nokick_timer.check()) set_state(ICESTATE_KICKED);
- break;
+ }
+ if (nokick_timer.check()) set_state(ICESTATE_KICKED);
+ break;
case ICESTATE_GRABBED:
assert(false);
break;
return ice_state == ICESTATE_FLAT;
}
-IMPLEMENT_FACTORY(MrIceBlock, "mriceblock")
+IMPLEMENT_FACTORY(MrIceBlock, "mriceblock");
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __MRICEBLOCK_H__
-#define __MRICEBLOCK_H__
+#ifndef HEADER_SUPERTUX_BADGUY_MRICEBLOCK_HPP
+#define HEADER_SUPERTUX_BADGUY_MRICEBLOCK_HPP
-#include "walking_badguy.hpp"
+#include "badguy/walking_badguy.hpp"
#include "object/portable.hpp"
-class MrIceBlock : public WalkingBadguy, public Portable
+class MrIceBlock : public WalkingBadguy,
+ public Portable
{
public:
- MrIceBlock(const lisp::Lisp& reader);
+ MrIceBlock(const Reader& reader);
MrIceBlock(const Vector& pos, Direction d);
void initialize();
- void write(lisp::Writer& writer);
HitResponse collision(GameObject& object, const CollisionHit& hit);
void collision_solid(const CollisionHit& hit);
HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
bool can_break();
- virtual MrIceBlock* clone() const { return new MrIceBlock(*this); }
-
protected:
- bool collision_squished(GameObject& object);
-
-private:
enum IceState {
ICESTATE_NORMAL,
ICESTATE_FLAT,
ICESTATE_KICKED
};
+protected:
+ bool collision_squished(GameObject& object);
void set_state(IceState state);
+private:
IceState ice_state;
Timer nokick_timer;
Timer flat_timer;
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "mrrocket.hpp"
+#include "badguy/mrrocket.hpp"
#include "object/explosion.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
-#include "sector.hpp"
#include "sprite/sprite.hpp"
+#include "supertux/object_factory.hpp"
+#include "supertux/sector.hpp"
static const float SPEED = 200;
-MrRocket::MrRocket(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/mr_rocket/mr_rocket.sprite")
+MrRocket::MrRocket(const Reader& reader) :
+ BadGuy(reader, "images/creatures/mr_rocket/mr_rocket.sprite"),
+ collision_timer()
{
}
-MrRocket::MrRocket(const Vector& pos, Direction d)
- : BadGuy(pos, d, "images/creatures/mr_rocket/mr_rocket.sprite")
+MrRocket::MrRocket(const Vector& pos, Direction d) :
+ BadGuy(pos, d, "images/creatures/mr_rocket/mr_rocket.sprite"),
+ collision_timer()
{
}
void
-MrRocket::write(lisp::Writer& writer)
-{
- writer.start_list("mrrocket");
-
- writer.write("x", start_position.x);
- writer.write("y", start_position.y);
-
- writer.end_list("mrrocket");
-}
-
-void
MrRocket::initialize()
{
physic.set_velocity_x(dir == LEFT ? -SPEED : SPEED);
remove_me();
}
else if (!collision_timer.started()) {
- movement=physic.get_movement(elapsed_time);
- sprite->set_action(dir == LEFT ? "left" : "right");
+ movement=physic.get_movement(elapsed_time);
+ sprite->set_action(dir == LEFT ? "left" : "right");
}
}
}
}
-IMPLEMENT_FACTORY(MrRocket, "mrrocket")
+IMPLEMENT_FACTORY(MrRocket, "mrrocket");
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __MRROCKET_H__
-#define __MRROCKET_H__
+#ifndef HEADER_SUPERTUX_BADGUY_MRROCKET_HPP
+#define HEADER_SUPERTUX_BADGUY_MRROCKET_HPP
-#include "badguy.hpp"
-#include "timer.hpp"
+#include "badguy/badguy.hpp"
class MrRocket : public BadGuy
{
public:
- MrRocket(const lisp::Lisp& reader);
+ MrRocket(const Reader& reader);
MrRocket(const Vector& pos, Direction d);
void initialize();
void active_update(float elapsed_time);
- void write(lisp::Writer& writer);
void collision_solid(const CollisionHit& hit);
- virtual MrRocket* clone() const { return new MrRocket(*this); }
-
protected:
bool collision_squished(GameObject& object);
+
+private:
Timer collision_timer;
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "mrtree.hpp"
+#include "badguy/mrtree.hpp"
-#include "stumpy.hpp"
-#include "poisonivy.hpp"
-#include "random_generator.hpp"
-#include "object/sprite_particle.hpp"
-#include "sector.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
#include "audio/sound_manager.hpp"
+#include "badguy/poisonivy.hpp"
+#include "badguy/stumpy.hpp"
+#include "math/random_generator.hpp"
+#include "object/player.hpp"
+#include "object/sprite_particle.hpp"
+#include "supertux/object_factory.hpp"
+#include "supertux/sector.hpp"
#include <math.h>
static const float POISONIVY_HEIGHT = 32;
static const float POISONIVY_Y_OFFSET = 24;
-
-MrTree::MrTree(const lisp::Lisp& reader)
+MrTree::MrTree(const Reader& reader)
: WalkingBadguy(reader, "images/creatures/mr_tree/mr_tree.sprite","left","right")
{
walk_speed = WALKSPEED;
sound_manager->preload("sounds/mr_tree.ogg");
}
-void
-MrTree::write(lisp::Writer& writer)
-{
- writer.start_list("mrtree");
- WalkingBadguy::write(writer);
- writer.end_list("mrtree");
-}
-
bool
MrTree::collision_squished(GameObject& object)
{
return true;
}
-IMPLEMENT_FACTORY(MrTree, "mrtree")
+IMPLEMENT_FACTORY(MrTree, "mrtree");
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __MRTREE_H__
-#define __MRTREE_H__
+#ifndef HEADER_SUPERTUX_BADGUY_MRTREE_HPP
+#define HEADER_SUPERTUX_BADGUY_MRTREE_HPP
-#include "walking_badguy.hpp"
+#include "badguy/walking_badguy.hpp"
class MrTree : public WalkingBadguy
{
public:
- MrTree(const lisp::Lisp& reader);
- void write(lisp::Writer& writer);
- virtual MrTree* clone() const { return new MrTree(*this); }
+ MrTree(const Reader& reader);
protected:
bool collision_squished(GameObject& object);
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "plant.hpp"
+#include "badguy/plant.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
#include "object/player.hpp"
#include "sprite/sprite.hpp"
+#include "supertux/object_factory.hpp"
static const float WALKSPEED = 80;
static const float WAKE_TIME = .5;
-Plant::Plant(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/plant/plant.sprite")
+Plant::Plant(const Reader& reader) :
+ BadGuy(reader, "images/creatures/plant/plant.sprite"),
+ timer(),
+ state()
{
state = PLANT_SLEEPING;
}
void
-Plant::write(lisp::Writer& writer)
-{
- writer.start_list("plant");
-
- writer.write("x", start_position.x);
- writer.write("y", start_position.y);
-
- writer.end_list("plant");
-}
-
-void
Plant::initialize()
{
//FIXME: turns sspiky around for debugging
}
-IMPLEMENT_FACTORY(Plant, "plant")
+IMPLEMENT_FACTORY(Plant, "plant");
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __PLANT_H__
-#define __PLANT_H__
+#ifndef HEADER_SUPERTUX_BADGUY_PLANT_HPP
+#define HEADER_SUPERTUX_BADGUY_PLANT_HPP
-#include "badguy.hpp"
+#include "badguy/badguy.hpp"
class Plant : public BadGuy
{
public:
- Plant(const lisp::Lisp& reader);
+ Plant(const Reader& reader);
void initialize();
- void write(lisp::Writer& writer);
void collision_solid(const CollisionHit& hit);
HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
void active_update(float elapsed_time);
- virtual Plant* clone() const { return new Plant(*this); }
-
protected:
- Timer timer;
-
enum PlantState {
PLANT_SLEEPING,
PLANT_WAKING,
PLANT_WALKING
};
- PlantState state;
+private:
+ Timer timer;
+ PlantState state;
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "poisonivy.hpp"
-#include "random_generator.hpp"
+#include "badguy/poisonivy.hpp"
+#include "math/random_generator.hpp"
#include "object/sprite_particle.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
-#include "sector.hpp"
+#include "supertux/object_factory.hpp"
+#include "supertux/sector.hpp"
#include <math.h>
-PoisonIvy::PoisonIvy(const lisp::Lisp& reader)
- : WalkingBadguy(reader, "images/creatures/poison_ivy/poison_ivy.sprite", "left", "right")
+PoisonIvy::PoisonIvy(const Reader& reader)
+ : WalkingBadguy(reader, "images/creatures/poison_ivy/poison_ivy.sprite", "left", "right")
{
walk_speed = 80;
}
PoisonIvy::PoisonIvy(const Vector& pos, Direction d)
- : WalkingBadguy(pos, d, "images/creatures/poison_ivy/poison_ivy.sprite", "left", "right")
+ : WalkingBadguy(pos, d, "images/creatures/poison_ivy/poison_ivy.sprite", "left", "right")
{
walk_speed = 80;
}
-void
-PoisonIvy::write(lisp::Writer& writer)
-{
- writer.start_list("poisonivy");
- WalkingBadguy::write(writer);
- writer.end_list("poisonivy");
-}
-
bool
PoisonIvy::collision_squished(GameObject& object)
{
return true;
}
-IMPLEMENT_FACTORY(PoisonIvy, "poisonivy")
+IMPLEMENT_FACTORY(PoisonIvy, "poisonivy");
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __POISONIVY_H__
-#define __POISONIVY_H__
+#ifndef HEADER_SUPERTUX_BADGUY_POISONIVY_HPP
+#define HEADER_SUPERTUX_BADGUY_POISONIVY_HPP
-#include "walking_badguy.hpp"
+#include "badguy/walking_badguy.hpp"
class PoisonIvy : public WalkingBadguy
{
public:
- PoisonIvy(const lisp::Lisp& reader);
+ PoisonIvy(const Reader& reader);
PoisonIvy(const Vector& pos, Direction d);
- void write(lisp::Writer& writer);
- virtual PoisonIvy* clone() const { return new PoisonIvy(*this); }
-
protected:
bool collision_squished(GameObject& object);
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux - "Will-O-Wisp" Badguy
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "root.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "timer.hpp"
+#include "badguy/root.hpp"
#include "sprite/sprite.hpp"
+#include "sprite/sprite_manager.hpp"
static const float SPEED_GROW = 256;
static const float SPEED_SHRINK = 128;
static const float HATCH_TIME = 0.75;
-Root::Root(const Vector& pos)
- : BadGuy(pos, "images/creatures/ghosttree/root.sprite", LAYER_TILES-1),
- mystate(STATE_APPEARING), offset_y(0)
+Root::Root(const Vector& pos) :
+ BadGuy(pos, "images/creatures/ghosttree/root.sprite", LAYER_TILES-1),
+ mystate(STATE_APPEARING),
+ base_sprite(),
+ offset_y(0),
+ hatch_timer()
{
- base_sprite.reset(sprite_manager->create("images/creatures/ghosttree/root-base.sprite"));
+ base_sprite = sprite_manager->create("images/creatures/ghosttree/root-base.sprite");
base_sprite->set_action("appearing", 1);
base_sprite->set_animation_loops(1); // TODO: necessary because set_action ignores loops for default action
physic.enable_gravity(false);
if ((mystate != STATE_APPEARING) && (mystate != STATE_VANISHING)) BadGuy::draw(context);
}
+/* EOF */
-// $Id$
-//
// SuperTux - Boss "GhostTree"
// Copyright (C) 2007 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#ifndef __ROOT_H__
-#define __ROOT_H__
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_BADGUY_ROOT_HPP
+#define HEADER_SUPERTUX_BADGUY_ROOT_HPP
-#include <memory>
-#include "badguy.hpp"
+#include "badguy/badguy.hpp"
class Timer;
enum MyState {
STATE_APPEARING, STATE_HATCHING, STATE_GROWING, STATE_SHRINKING, STATE_VANISHING
};
+
+private:
MyState mystate;
std::auto_ptr<Sprite> base_sprite;
float offset_y;
};
#endif
+
+/* EOF */
-// $Id$
-//
// SkullyHop - A Hopping Skull
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-#include <config.h>
-
-#include "skullyhop.hpp"
-#include "random_generator.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#include "badguy/skullyhop.hpp"
+
#include "audio/sound_manager.hpp"
+#include "math/random_generator.hpp"
#include "sprite/sprite.hpp"
+#include "supertux/object_factory.hpp"
namespace {
- const float VERTICAL_SPEED = -450; /**< y-speed when jumping */
- const float HORIZONTAL_SPEED = 220; /**< x-speed when jumping */
- const float MIN_RECOVER_TIME = 0.1f; /**< minimum time to stand still before starting a (new) jump */
- const float MAX_RECOVER_TIME = 1.0f; /**< maximum time to stand still before starting a (new) jump */
- static const std::string HOP_SOUND = "sounds/hop.ogg";
+const float VERTICAL_SPEED = -450; /**< y-speed when jumping */
+const float HORIZONTAL_SPEED = 220; /**< x-speed when jumping */
+const float MIN_RECOVER_TIME = 0.1f; /**< minimum time to stand still before starting a (new) jump */
+const float MAX_RECOVER_TIME = 1.0f; /**< maximum time to stand still before starting a (new) jump */
+static const std::string HOP_SOUND = "sounds/hop.ogg";
}
-SkullyHop::SkullyHop(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/skullyhop/skullyhop.sprite")
+SkullyHop::SkullyHop(const Reader& reader) :
+ BadGuy(reader, "images/creatures/skullyhop/skullyhop.sprite"),
+ recover_timer(),
+ state()
{
sound_manager->preload( HOP_SOUND );
}
-SkullyHop::SkullyHop(const Vector& pos, Direction d)
- : BadGuy(pos, d, "images/creatures/skullyhop/skullyhop.sprite")
+SkullyHop::SkullyHop(const Vector& pos, Direction d) :
+ BadGuy(pos, d, "images/creatures/skullyhop/skullyhop.sprite"),
+ recover_timer(),
+ state()
{
sound_manager->preload( HOP_SOUND );
}
void
-SkullyHop::write(lisp::Writer& writer)
-{
- writer.start_list("skullyhop");
- writer.write("x", start_position.x);
- writer.write("y", start_position.y);
- writer.end_list("skullyhop");
-}
-
-void
SkullyHop::initialize()
{
// initial state is JUMPING, because we might start airborne
float recover_time = systemRandom.randf(MIN_RECOVER_TIME,MAX_RECOVER_TIME);
recover_timer.start(recover_time);
} else
- if (newState == CHARGING) {
- sprite->set_action(dir == LEFT ? "charging-left" : "charging-right", 1);
- } else
- if (newState == JUMPING) {
- sprite->set_action(dir == LEFT ? "jumping-left" : "jumping-right");
- physic.set_velocity_x(dir == LEFT ? -HORIZONTAL_SPEED : HORIZONTAL_SPEED);
- physic.set_velocity_y(VERTICAL_SPEED);
- sound_manager->play( HOP_SOUND, get_pos());
- }
+ if (newState == CHARGING) {
+ sprite->set_action(dir == LEFT ? "charging-left" : "charging-right", 1);
+ } else
+ if (newState == JUMPING) {
+ sprite->set_action(dir == LEFT ? "jumping-left" : "jumping-right");
+ physic.set_velocity_x(dir == LEFT ? -HORIZONTAL_SPEED : HORIZONTAL_SPEED);
+ physic.set_velocity_y(VERTICAL_SPEED);
+ sound_manager->play( HOP_SOUND, get_pos());
+ }
state = newState;
}
}
}
-IMPLEMENT_FACTORY(SkullyHop, "skullyhop")
+IMPLEMENT_FACTORY(SkullyHop, "skullyhop");
+
+/* EOF */
-// $Id$
-//
// SkullyHop - A Hopping Skull
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __SKULLYHOP_H__
-#define __SKULLYHOP_H__
+#ifndef HEADER_SUPERTUX_BADGUY_SKULLYHOP_HPP
+#define HEADER_SUPERTUX_BADGUY_SKULLYHOP_HPP
-#include "badguy.hpp"
+#include "badguy/badguy.hpp"
/**
* Badguy "SkullyHop" - A Hopping Skull
class SkullyHop : public BadGuy
{
public:
- SkullyHop(const lisp::Lisp& reader);
+ SkullyHop(const Reader& reader);
SkullyHop(const Vector& pos, Direction d);
void initialize();
- void write(lisp::Writer& writer);
void collision_solid(const CollisionHit& hit);
HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
bool collision_squished(GameObject& object);
void active_update(float elapsed_time);
- virtual SkullyHop* clone() const { return new SkullyHop(*this); }
-
-protected:
+private:
enum SkullyHopState {
STANDING,
CHARGING,
JUMPING
};
+private:
+ void set_state(SkullyHopState newState);
+
+private:
Timer recover_timer;
SkullyHopState state;
-
- void set_state(SkullyHopState newState);
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux - Smart Snowball
// Copyright (C) 2008 Wolfgang Becker <uafr@gmx.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "smartball.hpp"
+#include "badguy/smartball.hpp"
-#include "object_factory.hpp"
#include "sprite/sprite.hpp"
+#include "supertux/object_factory.hpp"
-SmartBall::SmartBall(const lisp::Lisp& reader)
+SmartBall::SmartBall(const Reader& reader)
: WalkingBadguy(reader, "images/creatures/snowball/smart-snowball.sprite", "left", "right")
{
walk_speed = 80;
return true;
}
-IMPLEMENT_FACTORY(SmartBall, "smartball")
+IMPLEMENT_FACTORY(SmartBall, "smartball");
+
+/* EOF */
-// $Id$
-//
// SuperTux - Smart Snowball
// Copyright (C) 2008 Wolfgang Becker <uafr@gmx.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __SMARTBALL_H__
-#define __SMARTBALL_H__
+#ifndef HEADER_SUPERTUX_BADGUY_SMARTBALL_HPP
+#define HEADER_SUPERTUX_BADGUY_SMARTBALL_HPP
-#include "walking_badguy.hpp"
+#include "badguy/walking_badguy.hpp"
/*
* Easy to kill badguy that does not jump down from it's ledge.
class SmartBall : public WalkingBadguy
{
public:
- SmartBall(const lisp::Lisp& reader);
+ SmartBall(const Reader& reader);
SmartBall(const Vector& pos, Direction d);
- virtual SmartBall* clone() const { return new SmartBall(*this); }
-
protected:
bool collision_squished(GameObject& object);
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux - Badguy "Snail"
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "snail.hpp"
+#include "badguy/snail.hpp"
-#include "object/block.hpp"
-#include "lisp/writer.hpp"
-#include "sprite/sprite.hpp"
-#include "object_factory.hpp"
#include "audio/sound_manager.hpp"
#include "object/player.hpp"
+#include "sprite/sprite.hpp"
+#include "supertux/object_factory.hpp"
#include <math.h>
namespace {
- const float KICKSPEED = 500;
- const int MAXSQUISHES = 10;
- const float KICKSPEED_Y = -500; /**< y-velocity gained when kicked */
+const float KICKSPEED = 500;
+const int MAXSQUISHES = 10;
+const float KICKSPEED_Y = -500; /**< y-velocity gained when kicked */
}
-Snail::Snail(const lisp::Lisp& reader)
- : WalkingBadguy(reader, "images/creatures/snail/snail.sprite", "left", "right"), state(STATE_NORMAL), squishcount(0)
+Snail::Snail(const Reader& reader) :
+ WalkingBadguy(reader, "images/creatures/snail/snail.sprite", "left", "right"),
+ state(STATE_NORMAL),
+ flat_timer(),
+ kicked_delay_timer(),
+ squishcount(0)
{
walk_speed = 80;
max_drop_height = 600;
sound_manager->preload("sounds/kick.wav");
}
-Snail::Snail(const Vector& pos, Direction d)
- : WalkingBadguy(pos, d, "images/creatures/snail/snail.sprite", "left", "right"), state(STATE_NORMAL), squishcount(0)
+Snail::Snail(const Vector& pos, Direction d) :
+ WalkingBadguy(pos, d, "images/creatures/snail/snail.sprite", "left", "right"),
+ state(STATE_NORMAL),
+ flat_timer(),
+ kicked_delay_timer(),
+ squishcount(0)
{
walk_speed = 80;
max_drop_height = 600;
}
void
-Snail::write(lisp::Writer& writer)
-{
- writer.start_list("snail");
- WalkingBadguy::write(writer);
- writer.end_list("snail");
-}
-
-void
Snail::initialize()
{
WalkingBadguy::initialize();
bool
Snail::can_break(){
- return state == STATE_KICKED;
+ return state == STATE_KICKED;
}
void
case STATE_KICKED:
case STATE_NORMAL:
- {
- Player* player = dynamic_cast<Player*>(&object);
- squishcount++;
- if ((squishcount >= MAXSQUISHES) || (player && player->does_buttjump)) {
- kill_fall();
- return true;
- }
+ {
+ Player* player = dynamic_cast<Player*>(&object);
+ squishcount++;
+ if ((squishcount >= MAXSQUISHES) || (player && player->does_buttjump)) {
+ kill_fall();
+ return true;
}
+ }
- sound_manager->play("sounds/stomp.wav", get_pos());
- be_flat();
- break;
+ sound_manager->play("sounds/stomp.wav", get_pos());
+ be_flat();
+ break;
case STATE_FLAT:
sound_manager->play("sounds/kick.wav", get_pos());
return true;
}
-IMPLEMENT_FACTORY(Snail, "snail")
+IMPLEMENT_FACTORY(Snail, "snail");
+
+/* EOF */
-// $Id$
-//
// SuperTux - Badguy "Snail"
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __SNAIL_H__
-#define __SNAIL_H__
+#ifndef HEADER_SUPERTUX_BADGUY_SNAIL_HPP
+#define HEADER_SUPERTUX_BADGUY_SNAIL_HPP
-#include "walking_badguy.hpp"
+#include "badguy/walking_badguy.hpp"
/**
* Badguy "Snail" - a snail-like creature that can be flipped and tossed around at an angle
class Snail : public WalkingBadguy
{
public:
- Snail(const lisp::Lisp& reader);
+ Snail(const Reader& reader);
Snail(const Vector& pos, Direction d);
void initialize();
- void write(lisp::Writer& writer);
void collision_solid(const CollisionHit& hit);
HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
bool can_break();
void active_update(float elapsed_time);
- virtual Snail* clone() const { return new Snail(*this); }
-
protected:
bool collision_squished(GameObject& object);
void be_normal(); /**< switch to state STATE_NORMAL */
STATE_KICKED_DELAY, /**< short delay before being launched */
STATE_KICKED /**< launched */
};
+
+private:
State state;
Timer flat_timer; /**< wait time until flipping right-side-up again */
Timer kicked_delay_timer; /**< wait time until switching from STATE_KICKED_DELAY to STATE_KICKED */
- int squishcount;
+ int squishcount;
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "snowball.hpp"
+#include "badguy/snowball.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
#include "sprite/sprite.hpp"
+#include "supertux/object_factory.hpp"
-SnowBall::SnowBall(const lisp::Lisp& reader)
- : WalkingBadguy(reader, "images/creatures/snowball/snowball.sprite", "left", "right")
+SnowBall::SnowBall(const Reader& reader)
+ : WalkingBadguy(reader, "images/creatures/snowball/snowball.sprite", "left", "right")
{
walk_speed = 80;
}
SnowBall::SnowBall(const Vector& pos, Direction d)
- : WalkingBadguy(pos, d, "images/creatures/snowball/snowball.sprite", "left", "right")
+ : WalkingBadguy(pos, d, "images/creatures/snowball/snowball.sprite", "left", "right")
{
walk_speed = 80;
}
-void
-SnowBall::write(lisp::Writer& writer)
-{
- writer.start_list("snowball");
- WalkingBadguy::write(writer);
- writer.end_list("snowball");
-}
-
bool
SnowBall::collision_squished(GameObject& object)
{
return true;
}
-IMPLEMENT_FACTORY(SnowBall, "snowball")
+IMPLEMENT_FACTORY(SnowBall, "snowball");
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __SNOWBALL_H__
-#define __SNOWBALL_H__
+#ifndef HEADER_SUPERTUX_BADGUY_SNOWBALL_HPP
+#define HEADER_SUPERTUX_BADGUY_SNOWBALL_HPP
-#include "walking_badguy.hpp"
+#include "badguy/walking_badguy.hpp"
class SnowBall : public WalkingBadguy
{
public:
- SnowBall(const lisp::Lisp& reader);
+ SnowBall(const Reader& reader);
SnowBall(const Vector& pos, Direction d);
- void write(lisp::Writer& writer);
- virtual SnowBall* clone() const { return new SnowBall(*this); }
-
protected:
bool collision_squished(GameObject& object);
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
-#include <stdio.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "spidermite.hpp"
+#include "badguy/spidermite.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
#include "object/player.hpp"
#include "sprite/sprite.hpp"
+#include "supertux/object_factory.hpp"
static const float FLYTIME = 1.2f;
static const float FLYSPEED = -100.0f;
-SpiderMite::SpiderMite(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/spidermite/spidermite.sprite")
+SpiderMite::SpiderMite(const Reader& reader) :
+ BadGuy(reader, "images/creatures/spidermite/spidermite.sprite"),
+ mode(),
+ timer()
{
physic.enable_gravity(false);
}
-SpiderMite::SpiderMite(const Vector& pos)
- : BadGuy(pos, "images/creatures/spidermite/spidermite.sprite")
+SpiderMite::SpiderMite(const Vector& pos) :
+ BadGuy(pos, "images/creatures/spidermite/spidermite.sprite"),
+ mode(),
+ timer()
{
physic.enable_gravity(false);
}
void
-SpiderMite::write(lisp::Writer& writer)
-{
- writer.start_list("spidermite");
-
- writer.write("x", start_position.x);
- writer.write("y", start_position.y);
-
- writer.end_list("spidermite");
-}
-
-void
SpiderMite::initialize()
{
sprite->set_action(dir == LEFT ? "left" : "right");
}
}
-IMPLEMENT_FACTORY(SpiderMite, "spidermite")
+IMPLEMENT_FACTORY(SpiderMite, "spidermite");
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __SPIDERMITE_H__
-#define __SPIDERMITE_H__
+#ifndef HEADER_SUPERTUX_BADGUY_SPIDERMITE_HPP
+#define HEADER_SUPERTUX_BADGUY_SPIDERMITE_HPP
-#include "badguy.hpp"
+#include "badguy/badguy.hpp"
class SpiderMite : public BadGuy
{
public:
- SpiderMite(const lisp::Lisp& reader);
+ SpiderMite(const Reader& reader);
SpiderMite(const Vector& pos);
void initialize();
- void write(lisp::Writer& writer);
void active_update(float elapsed_time);
void collision_solid(const CollisionHit& hit);
- virtual SpiderMite* clone() const { return new SpiderMite(*this); }
-
protected:
enum SpiderMiteMode {
FLY_UP,
FLY_DOWN
};
- SpiderMiteMode mode;
+
+protected:
bool collision_squished(GameObject& object);
+
private:
+ SpiderMiteMode mode;
Timer timer;
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "spiky.hpp"
+#include "badguy/spiky.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
#include "sprite/sprite.hpp"
+#include "supertux/object_factory.hpp"
-Spiky::Spiky(const lisp::Lisp& reader)
- : WalkingBadguy(reader, "images/creatures/spiky/spiky.sprite", "left", "right")
+Spiky::Spiky(const Reader& reader)
+ : WalkingBadguy(reader, "images/creatures/spiky/spiky.sprite", "left", "right")
{
walk_speed = 80;
max_drop_height = 600;
}
void
-Spiky::write(lisp::Writer& writer)
-{
- writer.start_list("spiky");
- WalkingBadguy::write(writer);
- writer.end_list("spiky");
-}
-
-void
Spiky::freeze()
{
WalkingBadguy::freeze();
return true;
}
-IMPLEMENT_FACTORY(Spiky, "spiky")
+IMPLEMENT_FACTORY(Spiky, "spiky");
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __SPIKY_H__
-#define __SPIKY_H__
+#ifndef HEADER_SUPERTUX_BADGUY_SPIKY_HPP
+#define HEADER_SUPERTUX_BADGUY_SPIKY_HPP
-#include "walking_badguy.hpp"
+#include "badguy/walking_badguy.hpp"
class Spiky : public WalkingBadguy
{
public:
- Spiky(const lisp::Lisp& reader);
-
- void write(lisp::Writer& writer);
- virtual Spiky* clone() const { return new Spiky(*this); }
+ Spiky(const Reader& reader);
void freeze();
bool is_freezable() const;
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "sspiky.hpp"
+#include "badguy/sspiky.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
-#include "sprite/sprite.hpp"
#include "object/player.hpp"
+#include "sprite/sprite.hpp"
+#include "supertux/object_factory.hpp"
static const float WALKSPEED = 80;
-SSpiky::SSpiky(const lisp::Lisp& reader)
- : WalkingBadguy(reader, "images/creatures/spiky/sleepingspiky.sprite", "left", "right"), state(SSPIKY_SLEEPING)
+SSpiky::SSpiky(const Reader& reader)
+ : WalkingBadguy(reader, "images/creatures/spiky/sleepingspiky.sprite", "left", "right"), state(SSPIKY_SLEEPING)
{
walk_speed = WALKSPEED;
max_drop_height = -1;
}
void
-SSpiky::write(lisp::Writer& writer)
-{
- writer.start_list("sspiky");
- WalkingBadguy::write(writer);
- writer.end_list("sspiky");
-}
-
-void
SSpiky::initialize()
{
state = SSPIKY_SLEEPING;
return true;
}
-IMPLEMENT_FACTORY(SSpiky, "sspiky")
+IMPLEMENT_FACTORY(SSpiky, "sspiky");
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __SSPIKY_H__
-#define __SSPIKY_H__
+#ifndef HEADER_SUPERTUX_BADGUY_SSPIKY_HPP
+#define HEADER_SUPERTUX_BADGUY_SSPIKY_HPP
-#include "walking_badguy.hpp"
+#include "badguy/walking_badguy.hpp"
class SSpiky : public WalkingBadguy
{
public:
- SSpiky(const lisp::Lisp& reader);
+ SSpiky(const Reader& reader);
void initialize();
- void write(lisp::Writer& writer);
void collision_solid(const CollisionHit& hit);
HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
void active_update(float elapsed_time);
void freeze();
bool is_freezable() const;
- virtual SSpiky* clone() const { return new SSpiky(*this); }
-
protected:
enum SSpikyState {
SSPIKY_SLEEPING,
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "stalactite.hpp"
+#include "badguy/stalactite.hpp"
-#include "random_generator.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
+#include "math/random_generator.hpp"
#include "object/player.hpp"
#include "sprite/sprite.hpp"
+#include "supertux/object_factory.hpp"
static const int SHAKE_RANGE_X = 40;
static const float SHAKE_TIME = .8f;
static const float SQUISH_TIME = 2;
static const float SHAKE_RANGE_Y = 400;
-Stalactite::Stalactite(const lisp::Lisp& lisp)
- : BadGuy(lisp, "images/creatures/stalactite/stalactite.sprite", LAYER_TILES - 1), state(STALACTITE_HANGING)
+Stalactite::Stalactite(const Reader& lisp) :
+ BadGuy(lisp, "images/creatures/stalactite/stalactite.sprite", LAYER_TILES - 1),
+ timer(),
+ state(STALACTITE_HANGING)
{
countMe = false;
set_colgroup_active(COLGROUP_TOUCHABLE);
}
void
-Stalactite::write(lisp::Writer& writer)
-{
- writer.start_list("stalactite");
- writer.write("x", start_position.x);
- writer.write("y", start_position.y);
- writer.end_list("stalactite");
-}
-
-void
Stalactite::active_update(float elapsed_time)
{
if(state == STALACTITE_HANGING) {
Player* player = this->get_nearest_player();
if (player) {
if(player->get_bbox().p2.x > bbox.p1.x - SHAKE_RANGE_X
- && player->get_bbox().p1.x < bbox.p2.x + SHAKE_RANGE_X
- && player->get_bbox().p2.y > bbox.p1.y
- && player->get_bbox().p1.y < bbox.p2.y + SHAKE_RANGE_Y) {
+ && player->get_bbox().p1.x < bbox.p2.x + SHAKE_RANGE_X
+ && player->get_bbox().p2.y > bbox.p1.y
+ && player->get_bbox().p1.y < bbox.p2.y + SHAKE_RANGE_Y) {
timer.start(SHAKE_TIME);
state = STALACTITE_SHAKING;
}
}
HitResponse
-Stalactite::collision_player(Player& player)
+Stalactite::collision_player(Player& player, const CollisionHit& )
{
if(state != STALACTITE_SQUISHED) {
player.kill(false);
if(get_state() != STATE_ACTIVE)
return;
-
if(state == STALACTITE_SQUISHED) {
sprite->draw(context, get_pos(), LAYER_OBJECTS);
return;
remove_me();
}
-IMPLEMENT_FACTORY(Stalactite, "stalactite")
+IMPLEMENT_FACTORY(Stalactite, "stalactite");
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __STALACTITE_H__
-#define __STALACTITE_H__
+#ifndef HEADER_SUPERTUX_BADGUY_STALACTITE_HPP
+#define HEADER_SUPERTUX_BADGUY_STALACTITE_HPP
-#include "badguy.hpp"
+#include "badguy/badguy.hpp"
class Stalactite : public BadGuy
{
public:
- Stalactite(const lisp::Lisp& reader);
+ Stalactite(const Reader& reader);
void active_update(float elapsed_time);
- void write(lisp::Writer& writer);
void collision_solid(const CollisionHit& hit);
- HitResponse collision_player(Player& player);
+ HitResponse collision_player(Player& player, const CollisionHit& hit);
HitResponse collision_badguy(BadGuy& other, const CollisionHit& hit);
void kill_fall();
void draw(DrawingContext& context);
void deactivate();
- virtual Stalactite* clone() const { return new Stalactite(*this); }
-
void squish();
protected:
- Timer timer;
-
enum StalactiteState {
STALACTITE_HANGING,
STALACTITE_SHAKING,
STALACTITE_FALLING,
STALACTITE_SQUISHED
};
+
+protected:
+ Timer timer;
StalactiteState state;
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "stumpy.hpp"
+#include "badguy/stumpy.hpp"
-#include "poisonivy.hpp"
-#include "random_generator.hpp"
-#include "object/sprite_particle.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
#include "audio/sound_manager.hpp"
-#include "sector.hpp"
+#include "math/random_generator.hpp"
+#include "object/player.hpp"
+#include "object/sprite_particle.hpp"
+#include "supertux/object_factory.hpp"
+#include "supertux/sector.hpp"
#include <math.h>
static const float WALKSPEED = 120;
static const float INVINCIBLE_TIME = 1;
-Stumpy::Stumpy(const lisp::Lisp& reader)
- : WalkingBadguy(reader, "images/creatures/mr_tree/stumpy.sprite","left","right"), mystate(STATE_NORMAL)
+Stumpy::Stumpy(const Reader& reader) :
+ WalkingBadguy(reader, "images/creatures/mr_tree/stumpy.sprite","left","right"),
+ mystate(STATE_NORMAL),
+ invincible_timer()
{
walk_speed = WALKSPEED;
max_drop_height = 16;
sound_manager->preload("sounds/mr_treehit.ogg");
}
-Stumpy::Stumpy(const Vector& pos, Direction d)
- : WalkingBadguy(pos, d, "images/creatures/mr_tree/stumpy.sprite","left","right"), mystate(STATE_INVINCIBLE)
+Stumpy::Stumpy(const Vector& pos, Direction d) :
+ WalkingBadguy(pos, d, "images/creatures/mr_tree/stumpy.sprite","left","right"),
+ mystate(STATE_INVINCIBLE),
+ invincible_timer()
{
walk_speed = WALKSPEED;
max_drop_height = 16;
invincible_timer.start(INVINCIBLE_TIME);
}
-
-void
-Stumpy::write(lisp::Writer& writer)
-{
- writer.start_list("stumpy");
- WalkingBadguy::write(writer);
- writer.end_list("stumpy");
-}
-
void
Stumpy::initialize()
{
return CONTINUE;
}
-IMPLEMENT_FACTORY(Stumpy, "stumpy")
+IMPLEMENT_FACTORY(Stumpy, "stumpy");
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __STUMPY_H__
-#define __STUMPY_H__
+#ifndef HEADER_SUPERTUX_BADGUY_STUMPY_HPP
+#define HEADER_SUPERTUX_BADGUY_STUMPY_HPP
-#include "walking_badguy.hpp"
+#include "badguy/walking_badguy.hpp"
class Stumpy : public WalkingBadguy
{
public:
- Stumpy(const lisp::Lisp& reader);
+ Stumpy(const Reader& reader);
Stumpy(const Vector& pos, Direction d);
void initialize();
void active_update(float elapsed_time);
- void write(lisp::Writer& writer);
void collision_solid(const CollisionHit& hit);
HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
- virtual Stumpy* clone() const { return new Stumpy(*this); }
-
protected:
enum MyState {
STATE_INVINCIBLE, STATE_NORMAL
};
- MyState mystate;
-
- Timer invincible_timer;
+protected:
bool collision_squished(GameObject& object);
+
+private:
+ MyState mystate;
+ Timer invincible_timer;
};
#endif
+
+/* EOF */
-// $Id$
-//
// Toad - A jumping toad
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "toad.hpp"
+#include "badguy/toad.hpp"
-#include "random_generator.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
-#include "object/player.hpp"
#include "audio/sound_manager.hpp"
+#include "object/player.hpp"
#include "sprite/sprite.hpp"
+#include "supertux/object_factory.hpp"
namespace {
- const float VERTICAL_SPEED = -450; /**< y-speed when jumping */
- const float HORIZONTAL_SPEED = 320; /**< x-speed when jumping */
- const float RECOVER_TIME = 0.5; /**< time to stand still before starting a (new) jump */
- static const std::string HOP_SOUND = "sounds/hop.ogg";
+const float VERTICAL_SPEED = -450; /**< y-speed when jumping */
+const float HORIZONTAL_SPEED = 320; /**< x-speed when jumping */
+const float RECOVER_TIME = 0.5; /**< time to stand still before starting a (new) jump */
+static const std::string HOP_SOUND = "sounds/hop.ogg";
}
-Toad::Toad(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/toad/toad.sprite")
+Toad::Toad(const Reader& reader) :
+ BadGuy(reader, "images/creatures/toad/toad.sprite"),
+ recover_timer(),
+ state()
{
sound_manager->preload(HOP_SOUND);
}
-Toad::Toad(const Vector& pos, Direction d)
- : BadGuy(pos, d, "images/creatures/toad/toad.sprite")
+Toad::Toad(const Vector& pos, Direction d) :
+ BadGuy(pos, d, "images/creatures/toad/toad.sprite"),
+ recover_timer(),
+ state()
{
sound_manager->preload(HOP_SOUND);
}
void
-Toad::write(lisp::Writer& writer)
-{
- writer.start_list("toad");
- writer.write("x", start_position.x);
- writer.write("y", start_position.y);
- writer.end_list("toad");
-}
-
-void
Toad::initialize()
{
// initial state is JUMPING, because we might start airborne
recover_timer.start(RECOVER_TIME);
} else
- if (newState == JUMPING) {
- sprite->set_action(dir == LEFT ? "jumping-left" : "jumping-right");
- physic.set_velocity_x(dir == LEFT ? -HORIZONTAL_SPEED : HORIZONTAL_SPEED);
- physic.set_velocity_y(VERTICAL_SPEED);
- sound_manager->play( HOP_SOUND, get_pos());
- } else
- if (newState == FALLING) {
- Player* player = get_nearest_player();
- // face player
- if (player && (player->get_bbox().p2.x < get_bbox().p1.x) && (dir == RIGHT)) dir = LEFT;
- if (player && (player->get_bbox().p1.x > get_bbox().p2.x) && (dir == LEFT)) dir = RIGHT;
- sprite->set_action(dir == LEFT ? "idle-left" : "idle-right");
- }
+ if (newState == JUMPING) {
+ sprite->set_action(dir == LEFT ? "jumping-left" : "jumping-right");
+ physic.set_velocity_x(dir == LEFT ? -HORIZONTAL_SPEED : HORIZONTAL_SPEED);
+ physic.set_velocity_y(VERTICAL_SPEED);
+ sound_manager->play( HOP_SOUND, get_pos());
+ } else
+ if (newState == FALLING) {
+ Player* player = get_nearest_player();
+ // face player
+ if (player && (player->get_bbox().p2.x < get_bbox().p1.x) && (dir == RIGHT)) dir = LEFT;
+ if (player && (player->get_bbox().p1.x > get_bbox().p2.x) && (dir == LEFT)) dir = RIGHT;
+ sprite->set_action(dir == LEFT ? "idle-left" : "idle-right");
+ }
state = newState;
}
// check if we hit left or right while moving in either direction
if(((physic.get_velocity_x() < 0) && hit.left) || ((physic.get_velocity_x() > 0) && hit.right)) {
/*
- dir = dir == LEFT ? RIGHT : LEFT;
- if (state == JUMPING) {
+ dir = dir == LEFT ? RIGHT : LEFT;
+ if (state == JUMPING) {
sprite->set_action(dir == LEFT ? "jumping-left" : "jumping-right");
- } else {
+ } else {
sprite->set_action(dir == LEFT ? "idle-left" : "idle-right");
- }
+ }
*/
physic.set_velocity_x(-0.25*physic.get_velocity_x());
}
}
-IMPLEMENT_FACTORY(Toad, "toad")
+IMPLEMENT_FACTORY(Toad, "toad");
+
+/* EOF */
-// $Id$
-//
// Toad - A jumping toad
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __TOAD_H__
-#define __TOAD_H__
+#ifndef HEADER_SUPERTUX_BADGUY_TOAD_HPP
+#define HEADER_SUPERTUX_BADGUY_TOAD_HPP
-#include "badguy.hpp"
+#include "badguy/badguy.hpp"
/**
* Badguy "Toad" - A jumping toad
class Toad : public BadGuy
{
public:
- Toad(const lisp::Lisp& reader);
+ Toad(const Reader& reader);
Toad(const Vector& pos, Direction d);
void initialize();
- void write(lisp::Writer& writer);
void collision_solid(const CollisionHit& hit);
HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
bool collision_squished(GameObject& object);
void active_update(float elapsed_time);
- virtual Toad* clone() const { return new Toad(*this); }
-
protected:
enum ToadState {
IDLE,
FALLING
};
+private:
+ void set_state(ToadState newState);
+
+private:
Timer recover_timer;
ToadState state;
-
- void set_state(ToadState newState);
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux - "Totem" Badguy
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "totem.hpp"
+#include "badguy/totem.hpp"
-#include "log.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
-#include "object/player.hpp"
#include "audio/sound_manager.hpp"
-#include "sector.hpp"
+#include "object/player.hpp"
#include "sprite/sprite.hpp"
+#include "supertux/object_factory.hpp"
+#include "supertux/sector.hpp"
#include <math.h>
static const float JUMP_OFF_SPEED_Y = -500;
static const std::string LAND_ON_TOTEM_SOUND = "sounds/totem.ogg";
-Totem::Totem(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/totem/totem.sprite")
-{
- carrying = 0;
- carried_by = 0;
- sound_manager->preload( LAND_ON_TOTEM_SOUND );
-}
-
-Totem::Totem(const Totem& other)
- : BadGuy(other), carrying(other.carrying), carried_by(other.carried_by)
+Totem::Totem(const Reader& reader) :
+ BadGuy(reader, "images/creatures/totem/totem.sprite"),
+ carrying(0),
+ carried_by(0)
{
sound_manager->preload( LAND_ON_TOTEM_SOUND );
}
}
void
-Totem::write(lisp::Writer& writer)
-{
- writer.start_list("totem");
-
- writer.write("x", start_position.x);
- writer.write("y", start_position.y);
-
- writer.end_list("totem");
-}
-
-void
Totem::initialize()
{
if (!carried_by) {
sound_manager->play( LAND_ON_TOTEM_SOUND , get_pos());
-
this->synchronize_with(target);
}
this->initialize();
bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
-
physic.set_velocity_y(JUMP_OFF_SPEED_Y);
}
physic.set_velocity_y(base->physic.get_velocity_y());
}
+IMPLEMENT_FACTORY(Totem, "totem");
-IMPLEMENT_FACTORY(Totem, "totem")
+/* EOF */
-// $Id$
-//
// SuperTux - "Totem" Badguy
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __TOTEM_H__
-#define __TOTEM_H__
+#ifndef HEADER_SUPERTUX_BADGUY_TOTEM_HPP
+#define HEADER_SUPERTUX_BADGUY_TOTEM_HPP
-#include "badguy.hpp"
+#include "badguy/badguy.hpp"
/**
* "Totem" Badguy - A variable-height stack of wooden blocks
class Totem : public BadGuy
{
public:
- Totem(const lisp::Lisp& reader);
- Totem(const Totem& totem);
+ Totem(const Reader& reader);
~Totem();
void initialize();
void active_update(float elapsed_time);
- void write(lisp::Writer& writer);
void collision_solid(const CollisionHit& hit);
HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
- virtual Totem* clone() const { return new Totem(*this); }
virtual bool updatePointers(const GameObject* from_object, GameObject* to_object);
protected:
- Totem* carrying; /**< Totem we are currently carrying (or 0) */
- Totem* carried_by; /**< Totem by which we are currently carried (or 0) */
-
bool collision_squished(GameObject& object);
void kill_fall();
void jump_off(); /**< jump off current base */
void synchronize_with(Totem* baseTotem); /**< synchronize position and movement with baseTotem */
+
+private:
+ Totem* carrying; /**< Totem we are currently carrying (or 0) */
+ Totem* carried_by; /**< Totem by which we are currently carried (or 0) */
+
+private:
+ Totem(const Totem&);
+ Totem& operator=(const Totem&);
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux - "Will-O-Wisp" Badguy
// Copyright (C) 2007 Matthias Braun
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "treewillowisp.hpp"
+#include "badguy/treewillowisp.hpp"
-#include "ghosttree.hpp"
-#include "object/lantern.hpp"
+#include "audio/sound_manager.hpp"
#include "audio/sound_source.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
+#include "badguy/ghosttree.hpp"
+#include "object/lantern.hpp"
#include "object/player.hpp"
-#include "audio/sound_manager.hpp"
#include "sprite/sprite.hpp"
#include <math.h>
static const float SUCKSPEED = 25;
TreeWillOWisp::TreeWillOWisp(GhostTree* tree, const Vector& pos,
- float radius, float speed)
- : BadGuy(tree->get_pos() + pos, "images/creatures/willowisp/willowisp.sprite",
- LAYER_OBJECTS - 20), was_sucked(false), mystate(STATE_DEFAULT), tree(tree)
+ float radius, float speed) :
+ BadGuy(tree->get_pos() + pos, "images/creatures/willowisp/willowisp.sprite",
+ LAYER_OBJECTS - 20),
+ was_sucked(false),
+ mystate(STATE_DEFAULT),
+ color(),
+ angle(),
+ radius(),
+ speed(),
+ sound_source(),
+ tree(tree),
+ suck_target()
{
sound_manager->preload(SOUNDFILE);
return color;
}
+/* EOF */
-// $Id$
-//
// SuperTux - "Will-O-Wisp" Badguy
// Copyright (C) 2007 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __TREEWILLOWISP_H__
-#define __TREEWILLOWISP_H__
+#ifndef HEADER_SUPERTUX_BADGUY_TREEWILLOWISP_HPP
+#define HEADER_SUPERTUX_BADGUY_TREEWILLOWISP_HPP
-#include "badguy.hpp"
+#include "badguy/badguy.hpp"
class GhostTree;
class SoundSource;
*/
void vanish();
void start_sucking(Vector suck_target);
- bool was_sucked;
void active_update(float elapsed_time);
void set_color(const Color& color);
enum MyState {
STATE_DEFAULT, STATE_VANISHING, STATE_SUCKED
};
+
+public:
+ bool was_sucked;
+
+private:
MyState mystate;
Color color;
GhostTree* tree;
Vector suck_target;
+
+private:
+ TreeWillOWisp(const TreeWillOWisp&);
+ TreeWillOWisp& operator=(const TreeWillOWisp&);
};
#endif
+/* EOF */
-// $Id$
-//
// SuperTux - WalkingBadguy
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "walking_badguy.hpp"
+#include "badguy/walking_badguy.hpp"
-#include "log.hpp"
-#include "timer.hpp"
-#include "lisp/writer.hpp"
#include "sprite/sprite.hpp"
-WalkingBadguy::WalkingBadguy(const Vector& pos, const std::string& sprite_name, const std::string& walk_left_action, const std::string& walk_right_action, int layer)
- : BadGuy(pos, sprite_name, layer), walk_left_action(walk_left_action), walk_right_action(walk_right_action), walk_speed(80), max_drop_height(-1)
-{
-}
-
-WalkingBadguy::WalkingBadguy(const Vector& pos, Direction direction, const std::string& sprite_name, const std::string& walk_left_action, const std::string& walk_right_action, int layer)
- : BadGuy(pos, direction, sprite_name, layer), walk_left_action(walk_left_action), walk_right_action(walk_right_action), walk_speed(80), max_drop_height(-1)
+WalkingBadguy::WalkingBadguy(const Vector& pos,
+ const std::string& sprite_name,
+ const std::string& walk_left_action,
+ const std::string& walk_right_action,
+ int layer) :
+ BadGuy(pos, sprite_name, layer),
+ walk_left_action(walk_left_action),
+ walk_right_action(walk_right_action),
+ walk_speed(80),
+ max_drop_height(-1),
+ turn_around_timer(),
+ turn_around_counter()
{
}
-WalkingBadguy::WalkingBadguy(const lisp::Lisp& reader, const std::string& sprite_name, const std::string& walk_left_action, const std::string& walk_right_action, int layer)
- : BadGuy(reader, sprite_name, layer), walk_left_action(walk_left_action), walk_right_action(walk_right_action), walk_speed(80), max_drop_height(-1)
+WalkingBadguy::WalkingBadguy(const Vector& pos,
+ Direction direction,
+ const std::string& sprite_name,
+ const std::string& walk_left_action,
+ const std::string& walk_right_action,
+ int layer) :
+ BadGuy(pos, direction, sprite_name, layer),
+ walk_left_action(walk_left_action),
+ walk_right_action(walk_right_action),
+ walk_speed(80),
+ max_drop_height(-1),
+ turn_around_timer(),
+ turn_around_counter()
{
}
-void
-WalkingBadguy::write(lisp::Writer& writer)
+WalkingBadguy::WalkingBadguy(const Reader& reader,
+ const std::string& sprite_name,
+ const std::string& walk_left_action,
+ const std::string& walk_right_action,
+ int layer) :
+ BadGuy(reader, sprite_name, layer),
+ walk_left_action(walk_left_action),
+ walk_right_action(walk_right_action),
+ walk_speed(80),
+ max_drop_height(-1),
+ turn_around_timer(),
+ turn_around_counter()
{
- writer.write("x", start_position.x);
- writer.write("y", start_position.y);
}
void
WalkingBadguy::initialize();
}
-
float
WalkingBadguy::get_velocity_y() const
{
{
physic.set_velocity_y(vy);
}
+
+/* EOF */
-// $Id$
-//
// SuperTux - WalkingBadguy
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __WALKING_BADGUY_H__
-#define __WALKING_BADGUY_H__
+#ifndef HEADER_SUPERTUX_BADGUY_WALKING_BADGUY_HPP
+#define HEADER_SUPERTUX_BADGUY_WALKING_BADGUY_HPP
-#include "badguy.hpp"
+#include "badguy/badguy.hpp"
class Timer;
class WalkingBadguy : public BadGuy
{
public:
- WalkingBadguy(const Vector& pos, const std::string& sprite_name, const std::string& walk_left_action, const std::string& walk_right_action, int layer = LAYER_OBJECTS);
- WalkingBadguy(const Vector& pos, Direction direction, const std::string& sprite_name, const std::string& walk_left_action, const std::string& walk_right_action, int layer = LAYER_OBJECTS);
- WalkingBadguy(const lisp::Lisp& reader, const std::string& sprite_name, const std::string& walk_left_action, const std::string& walk_right_action, int layer = LAYER_OBJECTS);
+ WalkingBadguy(const Vector& pos,
+ const std::string& sprite_name,
+ const std::string& walk_left_action,
+ const std::string& walk_right_action,
+ int layer = LAYER_OBJECTS);
+ WalkingBadguy(const Vector& pos, Direction direction,
+ const std::string& sprite_name,
+ const std::string& walk_left_action,
+ const std::string& walk_right_action,
+ int layer = LAYER_OBJECTS);
+ WalkingBadguy(const Reader& reader,
+ const std::string& sprite_name,
+ const std::string& walk_left_action,
+ const std::string& walk_right_action,
+ int layer = LAYER_OBJECTS);
void initialize();
- void write(lisp::Writer& writer);
void active_update(float elapsed_time);
void collision_solid(const CollisionHit& hit);
HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
protected:
void turn_around();
+protected:
std::string walk_left_action;
std::string walk_right_action;
float walk_speed;
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux - Walking Leaf
// Copyright (C) 2006 Wolfgang Becker <uafr@gmx.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "walkingleaf.hpp"
+#include "badguy/walkingleaf.hpp"
-#include "random_generator.hpp"
#include "object/sprite_particle.hpp"
-#include "object_factory.hpp"
+#include "supertux/object_factory.hpp"
-WalkingLeaf::WalkingLeaf(const lisp::Lisp& reader)
- : WalkingBadguy(reader, "images/creatures/walkingleaf/walkingleaf.sprite", "left", "right")
+WalkingLeaf::WalkingLeaf(const Reader& reader) :
+ WalkingBadguy(reader, "images/creatures/walkingleaf/walkingleaf.sprite", "left", "right")
{
walk_speed = 60;
max_drop_height = 16;
}
WalkingLeaf::WalkingLeaf(const Vector& pos, Direction d)
- : WalkingBadguy(pos, d, "images/creatures/walkingleaf/walkingleaf.sprite", "left", "right")
+ : WalkingBadguy(pos, d, "images/creatures/walkingleaf/walkingleaf.sprite", "left", "right")
{
walk_speed = 60;
max_drop_height = 16;
return true;
}
-IMPLEMENT_FACTORY(WalkingLeaf, "walkingleaf")
+IMPLEMENT_FACTORY(WalkingLeaf, "walkingleaf");
+
+/* EOF */
-// $Id$
-//
// SuperTux - Walking Leaf
// Copyright (C) 2006 Wolfgang Becker <uafr@gmx.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __WALKINGLEAF_H__
-#define __WALKINGLEAF_H__
+#ifndef HEADER_SUPERTUX_BADGUY_WALKINGLEAF_HPP
+#define HEADER_SUPERTUX_BADGUY_WALKINGLEAF_HPP
-#include "walking_badguy.hpp"
+#include "badguy/walking_badguy.hpp"
/*
* Easy to kill badguy that does not jump down from it's ledge.
class WalkingLeaf : public WalkingBadguy
{
public:
- WalkingLeaf(const lisp::Lisp& reader);
+ WalkingLeaf(const Reader& reader);
WalkingLeaf(const Vector& pos, Direction d);
- virtual WalkingLeaf* clone() const { return new WalkingLeaf(*this); }
-
protected:
bool collision_squished(GameObject& object);
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux - "Will-O-Wisp" Badguy
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "willowisp.hpp"
+#include "badguy/willowisp.hpp"
-#include "log.hpp"
-#include "game_session.hpp"
+#include "audio/sound_manager.hpp"
+#include "audio/sound_source.hpp"
#include "object/lantern.hpp"
+#include "object/path_walker.hpp"
#include "object/player.hpp"
#include "scripting/squirrel_util.hpp"
-#include "object/path.hpp"
-#include "object/path_walker.hpp"
-#include "audio/sound_source.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
-#include "audio/sound_manager.hpp"
-#include "sector.hpp"
#include "sprite/sprite.hpp"
+#include "supertux/game_session.hpp"
+#include "supertux/object_factory.hpp"
+#include "supertux/sector.hpp"
static const float FLYSPEED = 64; /**< speed in px per second */
static const float TRACK_RANGE = 384; /**< at what distance to start tracking the player */
static const float VANISH_RANGE = 512; /**< at what distance to stop tracking and vanish */
static const std::string SOUNDFILE = "sounds/willowisp.wav";
-WillOWisp::WillOWisp(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/willowisp/willowisp.sprite", LAYER_FLOATINGOBJECTS), mystate(STATE_IDLE), target_sector("main"), target_spawnpoint("main")
+WillOWisp::WillOWisp(const Reader& reader) :
+ BadGuy(reader, "images/creatures/willowisp/willowisp.sprite", LAYER_FLOATINGOBJECTS),
+ mystate(STATE_IDLE),
+ target_sector("main"),
+ target_spawnpoint("main"),
+ hit_script(),
+ sound_source(),
+ path(),
+ walker(),
+ flyspeed(),
+ track_range(),
+ vanish_range()
{
bool running = false;
flyspeed = FLYSPEED;
Vector dist = (p2 - p1);
switch(mystate) {
- case STATE_STOPPED:
- break;
+ case STATE_STOPPED:
+ break;
- case STATE_IDLE:
- if (dist.norm() <= track_range) {
- mystate = STATE_TRACKING;
- }
- break;
+ case STATE_IDLE:
+ if (dist.norm() <= track_range) {
+ mystate = STATE_TRACKING;
+ }
+ break;
- case STATE_TRACKING:
- if (dist.norm() > vanish_range) {
- vanish();
- } else if (dist.norm() >= 1) {
- Vector dir = dist.unit();
- movement = dir * elapsed_time * flyspeed;
- } else {
- /* We somehow landed right on top of the player without colliding.
- * Sit tight and avoid a division by zero. */
- }
- sound_source->set_position(get_pos());
- break;
+ case STATE_TRACKING:
+ if (dist.norm() > vanish_range) {
+ vanish();
+ } else if (dist.norm() >= 1) {
+ Vector dir = dist.unit();
+ movement = dir * elapsed_time * flyspeed;
+ } else {
+ /* We somehow landed right on top of the player without colliding.
+ * Sit tight and avoid a division by zero. */
+ }
+ sound_source->set_position(get_pos());
+ break;
- case STATE_WARPING:
- if(sprite->animation_done()) {
- remove_me();
- }
+ case STATE_WARPING:
+ if(sprite->animation_done()) {
+ remove_me();
+ }
- case STATE_VANISHING: {
- Vector dir = dist.unit();
- movement = dir * elapsed_time * flyspeed;
- if(sprite->animation_done()) {
- remove_me();
+ case STATE_VANISHING: {
+ Vector dir = dist.unit();
+ movement = dir * elapsed_time * flyspeed;
+ if(sprite->animation_done()) {
+ remove_me();
+ }
+ break;
}
- break;
- }
- case STATE_PATHMOVING:
- case STATE_PATHMOVING_TRACK:
- if(walker.get() == NULL)
- return;
- movement = walker->advance(elapsed_time) - get_pos();
- if(mystate == STATE_PATHMOVING_TRACK && dist.norm() <= track_range) {
- mystate = STATE_TRACKING;
- }
- break;
+ case STATE_PATHMOVING:
+ case STATE_PATHMOVING_TRACK:
+ if(walker.get() == NULL)
+ return;
+ movement = walker->advance(elapsed_time) - get_pos();
+ if(mystate == STATE_PATHMOVING_TRACK && dist.norm() <= track_range) {
+ mystate = STATE_TRACKING;
+ }
+ break;
- default:
- assert(false);
+ default:
+ assert(false);
}
}
} else {
std::ostringstream msg;
msg << "Can't set unknown willowisp state '" << new_state << "', should "
- "be stopped, move_path, move_path_track or normal";
+ "be stopped, move_path, move_path_track or normal";
throw new std::runtime_error(msg.str());
}
}
Scripting::unexpose_object(vm, table_idx, name);
}
-IMPLEMENT_FACTORY(WillOWisp, "willowisp")
+IMPLEMENT_FACTORY(WillOWisp, "willowisp");
+
+/* EOF */
-// $Id$
-//
// SuperTux - "Will-O-Wisp" Badguy
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __WILLOWISP_H__
-#define __WILLOWISP_H__
+#ifndef HEADER_SUPERTUX_BADGUY_WILLOWISP_HPP
+#define HEADER_SUPERTUX_BADGUY_WILLOWISP_HPP
-#include "badguy.hpp"
+#include "badguy/badguy.hpp"
class Path;
class PathWalker;
class SoundSource;
-#include "script_interface.hpp"
#include "scripting/willowisp.hpp"
+#include "supertux/script_interface.hpp"
-class WillOWisp : public BadGuy, public Scripting::WillOWisp,
+class WillOWisp : public BadGuy,
+ public Scripting::WillOWisp,
public ScriptInterface
{
public:
- WillOWisp(const lisp::Lisp& reader);
+ WillOWisp(const Reader& reader);
void activate();
void deactivate();
STATE_STOPPED, STATE_IDLE, STATE_TRACKING, STATE_VANISHING, STATE_WARPING,
STATE_PATHMOVING, STATE_PATHMOVING_TRACK
};
+
+private:
MyState mystate;
std::string target_sector;
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux - Boss "Yeti"
// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "yeti.hpp"
+#include "badguy/yeti.hpp"
-#include "object/camera.hpp"
-#include "yeti_stalactite.hpp"
-#include "bouncing_snowball.hpp"
-#include "game_session.hpp"
-#include "level.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
#include "audio/sound_manager.hpp"
-#include "sector.hpp"
+#include "badguy/bouncing_snowball.hpp"
+#include "badguy/yeti_stalactite.hpp"
+#include "object/camera.hpp"
#include "object/player.hpp"
#include "sprite/sprite.hpp"
+#include "supertux/object_factory.hpp"
+#include "supertux/sector.hpp"
-#include <math.h>
#include <float.h>
+#include <math.h>
namespace {
- const float JUMP_DOWN_VX = 250; /**< horizontal speed while jumping off the dais */
- const float JUMP_DOWN_VY = -250; /**< vertical speed while jumping off the dais */
+const float JUMP_DOWN_VX = 250; /**< horizontal speed while jumping off the dais */
+const float JUMP_DOWN_VY = -250; /**< vertical speed while jumping off the dais */
- const float RUN_VX = 350; /**< horizontal speed while running */
+const float RUN_VX = 350; /**< horizontal speed while running */
- const float JUMP_UP_VX = 350; /**< horizontal speed while jumping on the dais */
- const float JUMP_UP_VY = -800; /**< vertical speed while jumping on the dais */
+const float JUMP_UP_VX = 350; /**< horizontal speed while jumping on the dais */
+const float JUMP_UP_VY = -800; /**< vertical speed while jumping on the dais */
- const float STOMP_VY = -250; /** vertical speed while stomping on the dais */
+const float STOMP_VY = -250; /** vertical speed while stomping on the dais */
- const float LEFT_STAND_X = 16; /**< x-coordinate of left dais' end position */
- const float RIGHT_STAND_X = 800-60-16; /**< x-coordinate of right dais' end position */
- const float LEFT_JUMP_X = LEFT_STAND_X+224; /**< x-coordinate of from where to jump on the left dais */
- const float RIGHT_JUMP_X = RIGHT_STAND_X-224; /**< x-coordinate of from where to jump on the right dais */
- const float STOMP_WAIT = .5; /**< time we stay on the dais before jumping again */
- const float SAFE_TIME = .5; /**< the time we are safe when tux just hit us */
- const int INITIAL_HITPOINTS = 3; /**< number of hits we can take */
+const float LEFT_STAND_X = 16; /**< x-coordinate of left dais' end position */
+const float RIGHT_STAND_X = 800-60-16; /**< x-coordinate of right dais' end position */
+const float LEFT_JUMP_X = LEFT_STAND_X+224; /**< x-coordinate of from where to jump on the left dais */
+const float RIGHT_JUMP_X = RIGHT_STAND_X-224; /**< x-coordinate of from where to jump on the right dais */
+const float STOMP_WAIT = .5; /**< time we stay on the dais before jumping again */
+const float SAFE_TIME = .5; /**< the time we are safe when tux just hit us */
+const int INITIAL_HITPOINTS = 3; /**< number of hits we can take */
- const float SQUISH_TIME = 5;
+const float SQUISH_TIME = 5;
}
-Yeti::Yeti(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/yeti/yeti.sprite")
+Yeti::Yeti(const Reader& reader) :
+ BadGuy(reader, "images/creatures/yeti/yeti.sprite"),
+ state(),
+ state_timer(),
+ safe_timer(),
+ stomp_count(),
+ hit_points(),
+ hud_head()
{
hit_points = INITIAL_HITPOINTS;
countMe = false;
}
void
-Yeti::write(lisp::Writer& writer)
-{
- writer.start_list("yeti");
-
- writer.write("x", start_position.x);
- writer.write("y", start_position.y);
-
- writer.end_list("yeti");
-}
-
-void
Yeti::drop_stalactite()
{
// make a stalactite falling down and shake camera a bit
}
}
-IMPLEMENT_FACTORY(Yeti, "yeti")
+IMPLEMENT_FACTORY(Yeti, "yeti");
+
+/* EOF */
-// $Id$
-//
// SuperTux - Boss "Yeti"
// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#ifndef __YETI_H__
-#define __YETI_H__
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "badguy.hpp"
+#ifndef HEADER_SUPERTUX_BADGUY_YETI_HPP
+#define HEADER_SUPERTUX_BADGUY_YETI_HPP
#include <memory>
+#include "badguy/badguy.hpp"
+
class Yeti : public BadGuy
{
public:
- Yeti(const lisp::Lisp& lisp);
+ Yeti(const Reader& lisp);
~Yeti();
void draw(DrawingContext& context);
- void write(lisp::Writer& writer);
void initialize();
void active_update(float elapsed_time);
void collision_solid(const CollisionHit& hit);
void kill_squished(GameObject& object);
void kill_fall();
- virtual Yeti* clone() const { return new Yeti((Yeti&)*this); }
-
private:
void run();
void jump_up();
void take_hit(Player& player);
+private:
enum YetiState {
JUMP_DOWN,
RUN,
BE_ANGRY,
SQUISHED
};
+
+private:
YetiState state;
Timer state_timer;
Timer safe_timer;
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "yeti_stalactite.hpp"
+#include "badguy/yeti_stalactite.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
+#include "supertux/object_factory.hpp"
static const float SHAKE_TIME = .8f;
-YetiStalactite::YetiStalactite(const lisp::Lisp& lisp)
+YetiStalactite::YetiStalactite(const Reader& lisp)
: Stalactite(lisp)
{
}
}
void
-YetiStalactite::write(lisp::Writer& writer)
-{
- writer.start_list("yeti_stalactite");
- writer.write("x", start_position.x);
- writer.write("y", start_position.y);
- writer.end_list("yeti_stalactite");
-}
-
-void
YetiStalactite::start_shaking()
{
timer.start(SHAKE_TIME);
Stalactite::active_update(elapsed_time);
}
-IMPLEMENT_FACTORY(YetiStalactite, "yeti_stalactite")
+IMPLEMENT_FACTORY(YetiStalactite, "yeti_stalactite");
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __YETI_STALACTITE_H__
-#define __YETI_STALACTITE_H__
+#ifndef HEADER_SUPERTUX_BADGUY_YETI_STALACTITE_HPP
+#define HEADER_SUPERTUX_BADGUY_YETI_STALACTITE_HPP
-#include "stalactite.hpp"
+#include "badguy/stalactite.hpp"
class YetiStalactite : public Stalactite
{
public:
- YetiStalactite(const lisp::Lisp& lisp);
+ YetiStalactite(const Reader& lisp);
virtual ~YetiStalactite();
- void write(lisp::Writer& );
void active_update(float elapsed_time);
void start_shaking();
bool is_hanging();
-
- virtual YetiStalactite* clone() const { return new YetiStalactite(*this); }
};
#endif
+
+/* EOF */
-// $Id$
-//
// Zeekling - flyer that swoops down when she spots the player
// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "zeekling.hpp"
+#include "badguy/zeekling.hpp"
#include <math.h>
-#include "random_generator.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
+#include "math/random_generator.hpp"
#include "object/player.hpp"
#include "sprite/sprite.hpp"
-
-Zeekling::Zeekling(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/zeekling/zeekling.sprite"), last_player(0)
+#include "supertux/object_factory.hpp"
+
+Zeekling::Zeekling(const Reader& reader) :
+ BadGuy(reader, "images/creatures/zeekling/zeekling.sprite"),
+ speed(),
+ diveRecoverTimer(),
+ state(),
+ last_player(0),
+ last_player_pos(),
+ last_self_pos()
{
state = FLYING;
speed = systemRandom.rand(130, 171);
physic.enable_gravity(false);
}
-Zeekling::Zeekling(const Vector& pos, Direction d)
- : BadGuy(pos, d, "images/creatures/zeekling/zeekling.sprite"), last_player(0)
+Zeekling::Zeekling(const Vector& pos, Direction d) :
+ BadGuy(pos, d, "images/creatures/zeekling/zeekling.sprite"),
+ speed(),
+ diveRecoverTimer(),
+ state(),
+ last_player(0),
+ last_player_pos(),
+ last_self_pos()
{
state = FLYING;
speed = systemRandom.rand(130, 171);
}
void
-Zeekling::write(lisp::Writer& writer)
-{
- writer.start_list("zeekling");
-
- writer.write("x", start_position.x);
- writer.write("y", start_position.y);
-
- writer.end_list("zeekling");
-}
-
-void
Zeekling::initialize()
{
physic.set_velocity_x(dir == LEFT ? -speed : speed);
sprite->set_action(dir == LEFT ? "left" : "right");
physic.set_velocity_x(dir == LEFT ? -speed : speed);
} else
- if (state == DIVING) {
- dir = (dir == LEFT ? RIGHT : LEFT);
- state = FLYING;
- sprite->set_action(dir == LEFT ? "left" : "right");
- physic.set_velocity_x(dir == LEFT ? -speed : speed);
- physic.set_velocity_y(0);
- } else
- if (state == CLIMBING) {
- dir = (dir == LEFT ? RIGHT : LEFT);
- sprite->set_action(dir == LEFT ? "left" : "right");
- physic.set_velocity_x(dir == LEFT ? -speed : speed);
- } else {
- assert(false);
- }
+ if (state == DIVING) {
+ dir = (dir == LEFT ? RIGHT : LEFT);
+ state = FLYING;
+ sprite->set_action(dir == LEFT ? "left" : "right");
+ physic.set_velocity_x(dir == LEFT ? -speed : speed);
+ physic.set_velocity_y(0);
+ } else
+ if (state == CLIMBING) {
+ dir = (dir == LEFT ? RIGHT : LEFT);
+ sprite->set_action(dir == LEFT ? "left" : "right");
+ physic.set_velocity_x(dir == LEFT ? -speed : speed);
+ } else {
+ assert(false);
+ }
}
void
if (state == FLYING) {
physic.set_velocity_y(0);
} else
- if (state == DIVING) {
- state = CLIMBING;
- physic.set_velocity_y(-speed);
- sprite->set_action(dir == LEFT ? "left" : "right");
- } else
- if (state == CLIMBING) {
- state = FLYING;
- physic.set_velocity_y(0);
- }
+ if (state == DIVING) {
+ state = CLIMBING;
+ physic.set_velocity_y(-speed);
+ sprite->set_action(dir == LEFT ? "left" : "right");
+ } else
+ if (state == CLIMBING) {
+ state = FLYING;
+ physic.set_velocity_y(0);
+ }
}
void
}
}
-IMPLEMENT_FACTORY(Zeekling, "zeekling")
+IMPLEMENT_FACTORY(Zeekling, "zeekling");
+
+/* EOF */
-// $Id$
-//
// Zeekling - flyer that swoops down when she spots the player
// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __ZEEKLING_H__
-#define __ZEEKLING_H__
+#ifndef HEADER_SUPERTUX_BADGUY_ZEEKLING_HPP
+#define HEADER_SUPERTUX_BADGUY_ZEEKLING_HPP
-#include "badguy.hpp"
+#include "badguy/badguy.hpp"
class Zeekling : public BadGuy
{
public:
- Zeekling(const lisp::Lisp& reader);
+ Zeekling(const Reader& reader);
Zeekling(const Vector& pos, Direction d);
void initialize();
- void write(lisp::Writer& writer);
void collision_solid(const CollisionHit& hit);
void active_update(float elapsed_time);
- virtual Zeekling* clone() const { return new Zeekling(*this); }
-
-protected:
+private:
bool collision_squished(GameObject& object);
- float speed;
-
- Timer diveRecoverTimer;
+ bool should_we_dive();
+ void onBumpHorizontal();
+ void onBumpVertical();
+private:
enum ZeeklingState {
FLYING,
DIVING,
CLIMBING
};
- ZeeklingState state;
private:
+ float speed;
+ Timer diveRecoverTimer;
+ ZeeklingState state;
const MovingObject* last_player; /**< last player we tracked */
Vector last_player_pos; /**< position we last spotted the player at */
Vector last_self_pos; /**< position we last were at */
- bool should_we_dive();
- void onBumpHorizontal();
- void onBumpVertical();
+private:
+ Zeekling(const Zeekling&);
+ Zeekling& operator=(const Zeekling&);
};
#endif
+
+/* EOF */
+++ /dev/null
-/*
- * BinReloc - a library for creating relocatable executables
- * Written by: Hongli Lai <h.lai@chello.nl>
- * http://autopackage.org/
- *
- * This source code is public domain. You can relicense this code
- * under whatever license you want.
- *
- * See http://autopackage.org/docs/binreloc/ for
- * more information and how to use this.
- */
-
-#ifndef __BINRELOC_C__
-#define __BINRELOC_C__
-
-// [Christoph] use config.h, which defines ENABLE_BINRELOC
-#include <config.h>
-
-#ifdef ENABLE_BINRELOC
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <unistd.h>
-#endif /* ENABLE_BINRELOC */
-#include <stdio.h>
-#include <stdlib.h>
-#include <limits.h>
-#include <string.h>
-#include "binreloc.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-
-
-/** @internal
- * Find the canonical filename of the executable. Returns the filename
- * (which must be freed) or NULL on error. If the parameter 'error' is
- * not NULL, the error code will be stored there, if an error occurred.
- */
-static char *
-_br_find_exe (BrInitError *error)
-{
-#ifndef ENABLE_BINRELOC
- if (error)
- *error = BR_INIT_ERROR_DISABLED;
- return NULL;
-#else
- char *path, *path2, *line, *result;
- size_t buf_size;
- ssize_t size;
- struct stat stat_buf;
- FILE *f;
-
- /* Read from /proc/self/exe (symlink) */
- if (sizeof (path) > SSIZE_MAX)
- buf_size = SSIZE_MAX - 1;
- else
- buf_size = PATH_MAX - 1;
- path = (char *) malloc (buf_size);
- if (path == NULL) {
- /* Cannot allocate memory. */
- if (error)
- *error = BR_INIT_ERROR_NOMEM;
- return NULL;
- }
- path2 = (char *) malloc (buf_size);
- if (path2 == NULL) {
- /* Cannot allocate memory. */
- if (error)
- *error = BR_INIT_ERROR_NOMEM;
- free (path);
- return NULL;
- }
-
- strncpy (path2, "/proc/self/exe", buf_size - 1);
-
- while (1) {
- int i;
-
- size = readlink (path2, path, buf_size - 1);
- if (size == -1) {
- /* Error. */
- free (path2);
- break;
- }
-
- /* readlink() success. */
- path[size] = '\0';
-
- /* Check whether the symlink's target is also a symlink.
- * We want to get the final target. */
- i = stat (path, &stat_buf);
- if (i == -1) {
- /* Error. */
- free (path2);
- break;
- }
-
- /* stat() success. */
- if (!S_ISLNK (stat_buf.st_mode)) {
- /* path is not a symlink. Done. */
- free (path2);
- return path;
- }
-
- /* path is a symlink. Continue loop and resolve this. */
- strncpy (path, path2, buf_size - 1);
- }
-
-
- /* readlink() or stat() failed; this can happen when the program is
- * running in Valgrind 2.2. Read from /proc/self/maps as fallback. */
-
- buf_size = PATH_MAX + 128;
- line = (char *) realloc (path, buf_size);
- if (line == NULL) {
- /* Cannot allocate memory. */
- free (path);
- if (error)
- *error = BR_INIT_ERROR_NOMEM;
- return NULL;
- }
-
- f = fopen ("/proc/self/maps", "r");
- if (f == NULL) {
- free (line);
- if (error)
- *error = BR_INIT_ERROR_OPEN_MAPS;
- return NULL;
- }
-
- /* The first entry should be the executable name. */
- result = fgets (line, (int) buf_size, f);
- if (result == NULL) {
- fclose (f);
- free (line);
- if (error)
- *error = BR_INIT_ERROR_READ_MAPS;
- return NULL;
- }
-
- /* Get rid of newline character. */
- buf_size = strlen (line);
- if (buf_size <= 0) {
- /* Huh? An empty string? */
- fclose (f);
- free (line);
- if (error)
- *error = BR_INIT_ERROR_INVALID_MAPS;
- return NULL;
- }
- if (line[buf_size - 1] == 10)
- line[buf_size - 1] = 0;
-
- /* Extract the filename; it is always an absolute path. */
- path = strchr (line, '/');
-
- /* Sanity check. */
- if (strstr (line, " r-xp ") == NULL || path == NULL) {
- fclose (f);
- free (line);
- if (error)
- *error = BR_INIT_ERROR_INVALID_MAPS;
- return NULL;
- }
-
- path = strdup (path);
- free (line);
- fclose (f);
- return path;
-#endif /* ENABLE_BINRELOC */
-}
-
-
-/** @internal
- * Find the canonical filename of the executable which owns symbol.
- * Returns a filename which must be freed, or NULL on error.
- */
-static char *
-_br_find_exe_for_symbol (const void *symbol, BrInitError *error)
-{
- symbol = symbol; // [Christoph] mark it as used
-#ifndef ENABLE_BINRELOC
- if (error)
- *error = BR_INIT_ERROR_DISABLED;
- return (char *) NULL;
-#else
- #define SIZE PATH_MAX + 100
- FILE *f;
- size_t address_string_len;
- char *address_string, line[SIZE], *found;
-
- if (symbol == NULL)
- return (char *) NULL;
-
- f = fopen ("/proc/self/maps", "r");
- if (f == NULL)
- return (char *) NULL;
-
- address_string_len = 4;
- address_string = (char *) malloc (address_string_len);
- found = (char *) NULL;
-
- while (!feof (f)) {
- char *start_addr, *end_addr, *end_addr_end, *file;
- void *start_addr_p, *end_addr_p;
- size_t len;
-
- if (fgets (line, SIZE, f) == NULL)
- break;
-
- /* Sanity check. */
- if (strstr (line, " r-xp ") == NULL || strchr (line, '/') == NULL)
- continue;
-
- /* Parse line. */
- start_addr = line;
- end_addr = strchr (line, '-');
- file = strchr (line, '/');
-
- /* More sanity check. */
- if (!(file > end_addr && end_addr != NULL && end_addr[0] == '-'))
- continue;
-
- end_addr[0] = '\0';
- end_addr++;
- end_addr_end = strchr (end_addr, ' ');
- if (end_addr_end == NULL)
- continue;
-
- end_addr_end[0] = '\0';
- len = strlen (file);
- if (len == 0)
- continue;
- if (file[len - 1] == '\n')
- file[len - 1] = '\0';
-
- /* Get rid of "(deleted)" from the filename. */
- len = strlen (file);
- if (len > 10 && strcmp (file + len - 10, " (deleted)") == 0)
- file[len - 10] = '\0';
-
- /* I don't know whether this can happen but better safe than sorry. */
- len = strlen (start_addr);
- if (len != strlen (end_addr))
- continue;
-
-
- /* Transform the addresses into a string in the form of 0xdeadbeef,
- * then transform that into a pointer. */
- if (address_string_len < len + 3) {
- address_string_len = len + 3;
- address_string = (char *) realloc (address_string, address_string_len);
- }
-
- memcpy (address_string, "0x", 2);
- memcpy (address_string + 2, start_addr, len);
- address_string[2 + len] = '\0';
- sscanf (address_string, "%p", &start_addr_p);
-
- memcpy (address_string, "0x", 2);
- memcpy (address_string + 2, end_addr, len);
- address_string[2 + len] = '\0';
- sscanf (address_string, "%p", &end_addr_p);
-
-
- if (symbol >= start_addr_p && symbol < end_addr_p) {
- found = file;
- break;
- }
- }
-
- free (address_string);
- fclose (f);
-
- if (found == NULL)
- return (char *) NULL;
- else
- return strdup (found);
-#endif /* ENABLE_BINRELOC */
-}
-
-
-#ifndef BINRELOC_RUNNING_DOXYGEN
- #undef NULL
- #define NULL ((void *) 0) /* typecasted as char* for C++ type safeness */
-#endif
-
-static char *exe = (char *) NULL;
-
-
-/** Initialize the BinReloc library (for applications).
- *
- * This function must be called before using any other BinReloc functions.
- * It attempts to locate the application's canonical filename.
- *
- * @note If you want to use BinReloc for a library, then you should call
- * br_init_lib() instead.
- *
- * @param error If BinReloc failed to initialize, then the error code will
- * be stored in this variable. Set to NULL if you want to
- * ignore this. See #BrInitError for a list of error codes.
- *
- * @returns 1 on success, 0 if BinReloc failed to initialize.
- */
-int
-br_init (BrInitError *error)
-{
- exe = _br_find_exe (error);
- return exe != NULL;
-}
-
-
-/** Initialize the BinReloc library (for libraries).
- *
- * This function must be called before using any other BinReloc functions.
- * It attempts to locate the calling library's canonical filename.
- *
- * @note The BinReloc source code MUST be included in your library, or this
- * function won't work correctly.
- *
- * @param error If BinReloc failed to initialize, then the error code will
- * be stored in this variable. Set to NULL if you want to
- * ignore this. See #BrInitError for a list of error codes.
- *
- * @returns 1 on success, 0 if a filename cannot be found.
- */
-int
-br_init_lib (BrInitError *error)
-{
- exe = _br_find_exe_for_symbol ((const void *) "", error);
- return exe != NULL;
-}
-
-
-/** Find the canonical filename of the current application.
- *
- * @param default_exe A default filename which will be used as fallback.
- * @returns A string containing the application's canonical filename,
- * which must be freed when no longer necessary. If BinReloc is
- * not initialized, or if br_init() failed, then a copy of
- * default_exe will be returned. If default_exe is NULL, then
- * NULL will be returned.
- */
-char *
-br_find_exe (const char *default_exe)
-{
- if (exe == (char *) NULL) {
- /* BinReloc is not initialized. */
- if (default_exe != (const char *) NULL)
- return strdup (default_exe);
- else
- return (char *) NULL;
- }
- return strdup (exe);
-}
-
-
-/** Locate the directory in which the current application is installed.
- *
- * The prefix is generated by the following pseudo-code evaluation:
- * \code
- * dirname(exename)
- * \endcode
- *
- * @param default_dir A default directory which will used as fallback.
- * @return A string containing the directory, which must be freed when no
- * longer necessary. If BinReloc is not initialized, or if the
- * initialization function failed, then a copy of default_dir
- * will be returned. If default_dir is NULL, then NULL will be
- * returned.
- */
-char *
-br_find_exe_dir (const char *default_dir)
-{
- if (exe == NULL) {
- /* BinReloc not initialized. */
- if (default_dir != NULL)
- return strdup (default_dir);
- else
- return NULL;
- }
-
- return br_dirname (exe);
-}
-
-
-/** Locate the prefix in which the current application is installed.
- *
- * The prefix is generated by the following pseudo-code evaluation:
- * \code
- * dirname(dirname(exename))
- * \endcode
- *
- * @param default_prefix A default prefix which will used as fallback.
- * @return A string containing the prefix, which must be freed when no
- * longer necessary. If BinReloc is not initialized, or if
- * the initialization function failed, then a copy of default_prefix
- * will be returned. If default_prefix is NULL, then NULL will be returned.
- */
-char *
-br_find_prefix (const char *default_prefix)
-{
- char *dir1, *dir2;
-
- if (exe == (char *) NULL) {
- /* BinReloc not initialized. */
- if (default_prefix != (const char *) NULL)
- return strdup (default_prefix);
- else
- return (char *) NULL;
- }
-
- dir1 = br_dirname (exe);
- dir2 = br_dirname (dir1);
- free (dir1);
- return dir2;
-}
-
-
-/** Locate the application's binary folder.
- *
- * The path is generated by the following pseudo-code evaluation:
- * \code
- * prefix + "/bin"
- * \endcode
- *
- * @param default_bin_dir A default path which will used as fallback.
- * @return A string containing the bin folder's path, which must be freed when
- * no longer necessary. If BinReloc is not initialized, or if
- * the initialization function failed, then a copy of default_bin_dir will
- * be returned. If default_bin_dir is NULL, then NULL will be returned.
- */
-char *
-br_find_bin_dir (const char *default_bin_dir)
-{
- char *prefix, *dir;
-
- prefix = br_find_prefix ((const char *) NULL);
- if (prefix == (char *) NULL) {
- /* BinReloc not initialized. */
- if (default_bin_dir != (const char *) NULL)
- return strdup (default_bin_dir);
- else
- return (char *) NULL;
- }
-
- dir = br_build_path (prefix, "bin");
- free (prefix);
- return dir;
-}
-
-
-/** Locate the application's superuser binary folder.
- *
- * The path is generated by the following pseudo-code evaluation:
- * \code
- * prefix + "/sbin"
- * \endcode
- *
- * @param default_sbin_dir A default path which will used as fallback.
- * @return A string containing the sbin folder's path, which must be freed when
- * no longer necessary. If BinReloc is not initialized, or if the
- * initialization function failed, then a copy of default_sbin_dir will
- * be returned. If default_bin_dir is NULL, then NULL will be returned.
- */
-char *
-br_find_sbin_dir (const char *default_sbin_dir)
-{
- char *prefix, *dir;
-
- prefix = br_find_prefix ((const char *) NULL);
- if (prefix == (char *) NULL) {
- /* BinReloc not initialized. */
- if (default_sbin_dir != (const char *) NULL)
- return strdup (default_sbin_dir);
- else
- return (char *) NULL;
- }
-
- dir = br_build_path (prefix, "sbin");
- free (prefix);
- return dir;
-}
-
-
-/** Locate the application's data folder.
- *
- * The path is generated by the following pseudo-code evaluation:
- * \code
- * prefix + "/share"
- * \endcode
- *
- * @param default_data_dir A default path which will used as fallback.
- * @return A string containing the data folder's path, which must be freed when
- * no longer necessary. If BinReloc is not initialized, or if the
- * initialization function failed, then a copy of default_data_dir
- * will be returned. If default_data_dir is NULL, then NULL will be
- * returned.
- */
-char *
-br_find_data_dir (const char *default_data_dir)
-{
- char *prefix, *dir;
-
- prefix = br_find_prefix ((const char *) NULL);
- if (prefix == (char *) NULL) {
- /* BinReloc not initialized. */
- if (default_data_dir != (const char *) NULL)
- return strdup (default_data_dir);
- else
- return (char *) NULL;
- }
-
- dir = br_build_path (prefix, "share");
- free (prefix);
- return dir;
-}
-
-
-/** Locate the application's localization folder.
- *
- * The path is generated by the following pseudo-code evaluation:
- * \code
- * prefix + "/share/locale"
- * \endcode
- *
- * @param default_locale_dir A default path which will used as fallback.
- * @return A string containing the localization folder's path, which must be freed when
- * no longer necessary. If BinReloc is not initialized, or if the
- * initialization function failed, then a copy of default_locale_dir will be returned.
- * If default_locale_dir is NULL, then NULL will be returned.
- */
-char *
-br_find_locale_dir (const char *default_locale_dir)
-{
- char *data_dir, *dir;
-
- data_dir = br_find_data_dir ((const char *) NULL);
- if (data_dir == (char *) NULL) {
- /* BinReloc not initialized. */
- if (default_locale_dir != (const char *) NULL)
- return strdup (default_locale_dir);
- else
- return (char *) NULL;
- }
-
- dir = br_build_path (data_dir, "locale");
- free (data_dir);
- return dir;
-}
-
-
-/** Locate the application's library folder.
- *
- * The path is generated by the following pseudo-code evaluation:
- * \code
- * prefix + "/lib"
- * \endcode
- *
- * @param default_lib_dir A default path which will used as fallback.
- * @return A string containing the library folder's path, which must be freed when
- * no longer necessary. If BinReloc is not initialized, or if the initialization
- * function failed, then a copy of default_lib_dir will be returned.
- * If default_lib_dir is NULL, then NULL will be returned.
- */
-char *
-br_find_lib_dir (const char *default_lib_dir)
-{
- char *prefix, *dir;
-
- prefix = br_find_prefix ((const char *) NULL);
- if (prefix == (char *) NULL) {
- /* BinReloc not initialized. */
- if (default_lib_dir != (const char *) NULL)
- return strdup (default_lib_dir);
- else
- return (char *) NULL;
- }
-
- dir = br_build_path (prefix, "lib");
- free (prefix);
- return dir;
-}
-
-
-/** Locate the application's libexec folder.
- *
- * The path is generated by the following pseudo-code evaluation:
- * \code
- * prefix + "/libexec"
- * \endcode
- *
- * @param default_libexec_dir A default path which will used as fallback.
- * @return A string containing the libexec folder's path, which must be freed when
- * no longer necessary. If BinReloc is not initialized, or if the initialization
- * function failed, then a copy of default_libexec_dir will be returned.
- * If default_libexec_dir is NULL, then NULL will be returned.
- */
-char *
-br_find_libexec_dir (const char *default_libexec_dir)
-{
- char *prefix, *dir;
-
- prefix = br_find_prefix ((const char *) NULL);
- if (prefix == (char *) NULL) {
- /* BinReloc not initialized. */
- if (default_libexec_dir != (const char *) NULL)
- return strdup (default_libexec_dir);
- else
- return (char *) NULL;
- }
-
- dir = br_build_path (prefix, "libexec");
- free (prefix);
- return dir;
-}
-
-
-/** Locate the application's configuration files folder.
- *
- * The path is generated by the following pseudo-code evaluation:
- * \code
- * prefix + "/etc"
- * \endcode
- *
- * @param default_etc_dir A default path which will used as fallback.
- * @return A string containing the etc folder's path, which must be freed when
- * no longer necessary. If BinReloc is not initialized, or if the initialization
- * function failed, then a copy of default_etc_dir will be returned.
- * If default_etc_dir is NULL, then NULL will be returned.
- */
-char *
-br_find_etc_dir (const char *default_etc_dir)
-{
- char *prefix, *dir;
-
- prefix = br_find_prefix ((const char *) NULL);
- if (prefix == (char *) NULL) {
- /* BinReloc not initialized. */
- if (default_etc_dir != (const char *) NULL)
- return strdup (default_etc_dir);
- else
- return (char *) NULL;
- }
-
- dir = br_build_path (prefix, "etc");
- free (prefix);
- return dir;
-}
-
-
-/***********************
- * Utility functions
- ***********************/
-
-/** Concatenate str1 and str2 to a newly allocated string.
- *
- * @param str1 A string.
- * @param str2 Another string.
- * @returns A newly-allocated string. This string should be freed when no longer needed.
- */
-char *
-br_strcat (const char *str1, const char *str2)
-{
- char *result;
- size_t len1, len2;
-
- if (str1 == NULL)
- str1 = "";
- if (str2 == NULL)
- str2 = "";
-
- len1 = strlen (str1);
- len2 = strlen (str2);
-
- result = (char *) malloc (len1 + len2 + 1);
- memcpy (result, str1, len1);
- memcpy (result + len1, str2, len2);
- result[len1 + len2] = '\0';
-
- return result;
-}
-
-
-char *
-br_build_path (const char *dir, const char *file)
-{
- char *dir2, *result;
- size_t len;
- int must_free = 0;
-
- len = strlen (dir);
- if (len > 0 && dir[len - 1] != '/') {
- dir2 = br_strcat (dir, "/");
- must_free = 1;
- } else
- dir2 = (char *) dir;
-
- result = br_strcat (dir2, file);
- if (must_free)
- free (dir2);
- return result;
-}
-
-
-/* Emulates glibc's strndup() */
-static char *
-br_strndup (const char *str, size_t size)
-{
- char *result = (char *) NULL;
- size_t len;
-
- if (str == (const char *) NULL)
- return (char *) NULL;
-
- len = strlen (str);
- if (len == 0)
- return strdup ("");
- if (size > len)
- size = len;
-
- result = (char *) malloc (len + 1);
- memcpy (result, str, size);
- result[size] = '\0';
- return result;
-}
-
-
-/** Extracts the directory component of a path.
- *
- * Similar to g_dirname() or the dirname commandline application.
- *
- * Example:
- * \code
- * br_dirname ("/usr/local/foobar"); --> Returns: "/usr/local"
- * \endcode
- *
- * @param path A path.
- * @returns A directory name. This string should be freed when no longer needed.
- */
-char *
-br_dirname (const char *path)
-{
- char *end, *result;
-
- if (path == (const char *) NULL)
- return (char *) NULL;
-
- end = strrchr (path, '/');
- if (end == (const char *) NULL)
- return strdup (".");
-
- while (end > path && *end == '/')
- end--;
- result = br_strndup (path, end - path + 1);
- if (result[0] == 0) {
- free (result);
- return strdup ("/");
- } else
- return result;
-}
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __BINRELOC_C__ */
+++ /dev/null
-/*
- * BinReloc - a library for creating relocatable executables
- * Written by: Hongli Lai <h.lai@chello.nl>
- * http://autopackage.org/
- *
- * This source code is public domain. You can relicense this code
- * under whatever license you want.
- *
- * See http://autopackage.org/docs/binreloc/ for
- * more information and how to use this.
- */
-
-#ifndef __BINRELOC_H__
-#define __BINRELOC_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-
-/** These error codes can be returned by br_init(), br_init_lib(), gbr_init() or gbr_init_lib(). */
-typedef enum {
- /** Cannot allocate memory. */
- BR_INIT_ERROR_NOMEM,
- /** Unable to open /proc/self/maps; see errno for details. */
- BR_INIT_ERROR_OPEN_MAPS,
- /** Unable to read from /proc/self/maps; see errno for details. */
- BR_INIT_ERROR_READ_MAPS,
- /** The file format of /proc/self/maps is invalid; kernel bug? */
- BR_INIT_ERROR_INVALID_MAPS,
- /** BinReloc is disabled (the ENABLE_BINRELOC macro is not defined). */
- BR_INIT_ERROR_DISABLED
-} BrInitError;
-
-
-#ifndef BINRELOC_RUNNING_DOXYGEN
-/* Mangle symbol names to avoid symbol collisions with other ELF objects. */
- #define br_init PTeH3518859728963_br_init
- #define br_init_lib PTeH3518859728963_br_init_lib
- #define br_find_exe PTeH3518859728963_br_find_exe
- #define br_find_exe_dir PTeH3518859728963_br_find_exe_dir
- #define br_find_prefix PTeH3518859728963_br_find_prefix
- #define br_find_bin_dir PTeH3518859728963_br_find_bin_dir
- #define br_find_sbin_dir PTeH3518859728963_br_find_sbin_dir
- #define br_find_data_dir PTeH3518859728963_br_find_data_dir
- #define br_find_locale_dir PTeH3518859728963_br_find_locale_dir
- #define br_find_lib_dir PTeH3518859728963_br_find_lib_dir
- #define br_find_libexec_dir PTeH3518859728963_br_find_libexec_dir
- #define br_find_etc_dir PTeH3518859728963_br_find_etc_dir
- #define br_strcat PTeH3518859728963_br_strcat
- #define br_build_path PTeH3518859728963_br_build_path
- #define br_dirname PTeH3518859728963_br_dirname
-
-
-#endif
-int br_init (BrInitError *error);
-int br_init_lib (BrInitError *error);
-
-char *br_find_exe (const char *default_exe);
-char *br_find_exe_dir (const char *default_dir);
-char *br_find_prefix (const char *default_prefix);
-char *br_find_bin_dir (const char *default_bin_dir);
-char *br_find_sbin_dir (const char *default_sbin_dir);
-char *br_find_data_dir (const char *default_data_dir);
-char *br_find_locale_dir (const char *default_locale_dir);
-char *br_find_lib_dir (const char *default_lib_dir);
-char *br_find_libexec_dir (const char *default_libexec_dir);
-char *br_find_etc_dir (const char *default_etc_dir);
-
-/* Utility functions */
-char *br_strcat (const char *str1, const char *str2);
-char *br_build_path (const char *dir, const char *file);
-char *br_dirname (const char *path);
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __BINRELOC_H__ */
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-#include <config.h>
-
-#include "collision.hpp"
-
-#include <algorithm>
-#include <iostream>
-#include <stdio.h>
-#include <float.h>
-#include <math.h>
-#include "math/vector.hpp"
-#include "math/aatriangle.hpp"
-#include "math/rect.hpp"
-#include "collision_hit.hpp"
-#include "log.hpp"
-
-namespace collision
-{
-
-bool intersects(const Rect& r1, const Rect& r2)
-{
- if(r1.p2.x < r2.p1.x || r1.p1.x > r2.p2.x)
- return false;
- if(r1.p2.y < r2.p1.y || r1.p1.y > r2.p2.y)
- return false;
-
- return true;
-}
-
-//---------------------------------------------------------------------------
-
-namespace {
- inline void makePlane(const Vector& p1, const Vector& p2, Vector& n, float& c)
- {
- n = Vector(p2.y-p1.y, p1.x-p2.x);
- c = -(p2 * n);
- float nval = n.norm();
- n /= nval;
- c /= nval;
- }
-
-}
-
-bool rectangle_aatriangle(Constraints* constraints, const Rect& rect,
- const AATriangle& triangle, const Vector& addl_ground_movement)
-{
- if(!intersects(rect, (const Rect&) triangle))
- return false;
-
- Vector normal;
- float c;
- Vector p1;
- Rect area;
- switch(triangle.dir & AATriangle::DEFORM_MASK) {
- case 0:
- area.p1 = triangle.p1;
- area.p2 = triangle.p2;
- break;
- case AATriangle::DEFORM1:
- area.p1 = Vector(triangle.p1.x, triangle.p1.y + triangle.get_height()/2);
- area.p2 = triangle.p2;
- break;
- case AATriangle::DEFORM2:
- area.p1 = triangle.p1;
- area.p2 = Vector(triangle.p2.x, triangle.p1.y + triangle.get_height()/2);
- break;
- case AATriangle::DEFORM3:
- area.p1 = triangle.p1;
- area.p2 = Vector(triangle.p1.x + triangle.get_width()/2, triangle.p2.y);
- break;
- case AATriangle::DEFORM4:
- area.p1 = Vector(triangle.p1.x + triangle.get_width()/2, triangle.p1.y);
- area.p2 = triangle.p2;
- break;
- default:
- assert(false);
- }
-
- switch(triangle.dir & AATriangle::DIRECTION_MASK) {
- case AATriangle::SOUTHWEST:
- p1 = Vector(rect.p1.x, rect.p2.y);
- makePlane(area.p1, area.p2, normal, c);
- break;
- case AATriangle::NORTHEAST:
- p1 = Vector(rect.p2.x, rect.p1.y);
- makePlane(area.p2, area.p1, normal, c);
- break;
- case AATriangle::SOUTHEAST:
- p1 = rect.p2;
- makePlane(Vector(area.p1.x, area.p2.y),
- Vector(area.p2.x, area.p1.y), normal, c);
- break;
- case AATriangle::NORTHWEST:
- p1 = rect.p1;
- makePlane(Vector(area.p2.x, area.p1.y),
- Vector(area.p1.x, area.p2.y), normal, c);
- break;
- default:
- assert(false);
- }
-
- float n_p1 = -(normal * p1);
- float depth = n_p1 - c;
- if(depth < 0)
- return false;
-
-#if 0
- std::cout << "R: " << rect << " Tri: " << triangle << "\n";
- std::cout << "Norm: " << normal << " Depth: " << depth << "\n";
-#endif
-
- Vector outvec = normal * (depth + 0.2f);
-
- const float RDELTA = 3;
- if(p1.x < area.p1.x - RDELTA || p1.x > area.p2.x + RDELTA
- || p1.y < area.p1.y - RDELTA || p1.y > area.p2.y + RDELTA) {
- set_rectangle_rectangle_constraints(constraints, rect, area);
- constraints->hit.left = false;
- constraints->hit.right = false;
- } else {
- if(outvec.x < 0) {
- constraints->right = rect.get_right() + outvec.x;
- } else {
- constraints->left = rect.get_left() + outvec.x;
- }
-
- if(outvec.y < 0) {
- constraints->bottom = rect.get_bottom() + outvec.y;
- constraints->hit.bottom = true;
- constraints->ground_movement += addl_ground_movement;
- } else {
- constraints->top = rect.get_top() + outvec.y;
- constraints->hit.top = true;
- }
- constraints->hit.slope_normal = normal;
- }
-
- return true;
-}
-
-void set_rectangle_rectangle_constraints(Constraints* constraints,
- const Rect& r1, const Rect& r2, const Vector& addl_ground_movement)
-{
- float itop = r1.get_bottom() - r2.get_top();
- float ibottom = r2.get_bottom() - r1.get_top();
- float ileft = r1.get_right() - r2.get_left();
- float iright = r2.get_right() - r1.get_left();
-
- float vert_penetration = std::min(itop, ibottom);
- float horiz_penetration = std::min(ileft, iright);
- if(vert_penetration < horiz_penetration) {
- if(itop < ibottom) {
- constraints->bottom = std::min(constraints->bottom, r2.get_top());
- constraints->hit.bottom = true;
- constraints->ground_movement += addl_ground_movement;
- } else {
- constraints->top = std::max(constraints->top, r2.get_bottom());
- constraints->hit.top = true;
- }
- } else {
- if(ileft < iright) {
- constraints->right = std::min(constraints->right, r2.get_left());
- constraints->hit.right = true;
- } else {
- constraints->left = std::max(constraints->left, r2.get_right());
- constraints->hit.left = true;
- }
- }
-}
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-#ifndef __COLLISION_H__
-#define __COLLISION_H__
-
-#include <float.h>
-#include "collision_hit.hpp"
-#include <limits>
-
-class Vector;
-class Rect;
-class AATriangle;
-
-namespace collision
-{
-
-class Constraints
-{
-public:
- Constraints() {
- float infinity = (std::numeric_limits<float>::has_infinity ? std::numeric_limits<float>::infinity() : std::numeric_limits<float>::max());
- left = -infinity;
- right = infinity;
- top = -infinity;
- bottom = infinity;
- }
-
- bool has_constraints() const {
- float infinity = (std::numeric_limits<float>::has_infinity ? std::numeric_limits<float>::infinity() : std::numeric_limits<float>::max());
- return left > -infinity || right < infinity
- || top > -infinity || bottom < infinity;
- }
-
- float left;
- float right;
- float top;
- float bottom;
- Vector ground_movement;
- CollisionHit hit;
-};
-
-/** checks if 2 rectangle intersect each other */
-bool intersects(const Rect& r1, const Rect& r2);
-
-/** does collision detection between a rectangle and an axis aligned triangle
- * Returns true in case of a collision and fills in the hit structure then.
- */
-bool rectangle_aatriangle(Constraints* constraints, const Rect& rect,
- const AATriangle& triangle, const Vector& addl_ground_movement = Vector(0,0));
-
-void set_rectangle_rectangle_constraints(Constraints* constraints,
- const Rect& r1, const Rect& r2, const Vector& addl_ground_movement = Vector(0,0));
-
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#ifndef SUPERTUX_COLLISION_HIT_H
-#define SUPERTUX_COLLISION_HIT_H
-
-#include "math/vector.hpp"
-
-/**
- * Used as return value for the collision functions, to indicate how the
- * collision should be handled
- */
-enum HitResponse
-{
- /// don't move the object
- ABORT_MOVE = 0,
- /// move object out of collision and check for collisions again
- /// if this happens to often then the move will just be aborted
- CONTINUE,
- /// do the move ignoring the collision
- FORCE_MOVE,
- /// passes movement to collided object
- PASS_MOVEMENT,
-
- /// the object should not appear solid
- PASSTHROUGH,
- /// the object should appear solid
- SOLID,
-};
-
-/**
- * This class collects data about a collision
- */
-class CollisionHit
-{
-public:
- CollisionHit() {
- left = false;
- right = false;
- top = false;
- bottom = false;
- crush = false;
- }
-
- bool left, right;
- bool top, bottom;
- bool crush;
-
- Vector slope_normal;
-};
-
-#endif
+++ /dev/null
-#include "video/color.hpp"
-
-namespace LevelIntro {
- Color header_color(1.0,1.0,0.6);
- Color author_color(1.0,1.0,1.0);
- Color stat_hdr_color(0.2,0.5,1.0);
- Color stat_color(1.0,1.0,1.0);
-}
-
-namespace Statistics {
- Color header_color(1.0,1.0,1.0);
- Color text_color(1.0,1.0,0.6);
-}
-
-namespace Menu {
- Color default_color(1.0,1.0,1.0);
- Color active_color(0.2,0.5,1.0);
- Color inactive_color(0.5,0.5,0.5);
- Color label_color(0.0,1.0,1.0);
- Color field_color(1.0,1.0,0.6);
-}
-
-namespace PlayerStatus {
- Color text_color(1.0,1.0,0.6);
-}
-
-namespace TextObject {
- Color default_color(1.0,1.0,1.0);
-}
-
-namespace FloatingText {
- Color text_color(1.0,1.0,0.6);
-}
-
-namespace LevelTime {
- Color text_color(1.0,1.0,0.6);
-}
-
-namespace SecretAreaTrigger {
- Color text_color(1.0,1.0,0.6);
-}
-
-namespace Climbable {
- Color text_color(1.0,1.0,0.6);
-}
-
-namespace WorldMapNS {
- namespace WorldMap {
- Color level_title_color(1.0,1.0,1.0);
- Color message_color(1.0,1.0,0.6);
- Color teleporter_message_color(1.0,1.0,1.0);
-}}
-
-namespace TextScroller {
- Color small_color(1.0,1.0,1.0);
- Color heading_color(1.0,1.0,0.6);
- Color reference_color(0.2,0.6,1.0);
- Color normal_color(1.0,1.0,1.0);
-}
-
+++ /dev/null
-// $Id$
-//
-// SuperTux - Console
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include <config.h>
-
-#include <iostream>
-#include <math.h>
-#include <SDL_timer.h>
-#include <SDL_keyboard.h>
-#include "console.hpp"
-#include "video/drawing_context.hpp"
-#include "video/surface.hpp"
-#include "scripting/squirrel_error.hpp"
-#include "scripting/squirrel_util.hpp"
-#include "physfs/physfs_stream.hpp"
-#include "player_status.hpp"
-#include "main.hpp"
-#include "log.hpp"
-#include "resources.hpp"
-#include "gameconfig.hpp"
-
-/// speed (pixels/s) the console closes
-static const float FADE_SPEED = 1;
-
-Console::Console()
- : history_position(history.end()), vm(NULL), backgroundOffset(0),
- height(0), alpha(1.0), offset(0), focused(false), stayOpen(0) {
- fontheight = 8;
-}
-
-Console::~Console()
-{
- if(vm != NULL) {
- sq_release(Scripting::global_vm, &vm_object);
- }
-}
-
-void
-Console::init_graphics()
-{
- font.reset(new Font(Font::FIXED,"fonts/andale12.stf",1));
- fontheight = font->get_height();
- background.reset(new Surface("images/engine/console.png"));
- background2.reset(new Surface("images/engine/console2.png"));
-}
-
-void
-Console::flush(ConsoleStreamBuffer* buffer)
-{
- if (buffer == &outputBuffer) {
- std::string s = outputBuffer.str();
- if ((s.length() > 0) && ((s[s.length()-1] == '\n') || (s[s.length()-1] == '\r'))) {
- while ((s[s.length()-1] == '\n') || (s[s.length()-1] == '\r')) s.erase(s.length()-1);
- addLines(s);
- outputBuffer.str(std::string());
- }
- }
-}
-
-void
-Console::ready_vm()
-{
- if(vm == NULL) {
- vm = Scripting::global_vm;
- HSQUIRRELVM new_vm = sq_newthread(vm, 16);
- if(new_vm == NULL)
- throw Scripting::SquirrelError(vm, "Couldn't create new VM thread for console");
-
- // store reference to thread
- sq_resetobject(&vm_object);
- if(SQ_FAILED(sq_getstackobj(vm, -1, &vm_object)))
- throw Scripting::SquirrelError(vm, "Couldn't get vm object for console");
- sq_addref(vm, &vm_object);
- sq_pop(vm, 1);
-
- // create new roottable for thread
- sq_newtable(new_vm);
- sq_pushroottable(new_vm);
- if(SQ_FAILED(sq_setdelegate(new_vm, -2)))
- throw Scripting::SquirrelError(new_vm, "Couldn't set console_table delegate");
-
- sq_setroottable(new_vm);
-
- vm = new_vm;
-
- try {
- std::string filename = "scripts/console.nut";
- IFileStream stream(filename);
- Scripting::compile_and_run(vm, stream, filename);
- } catch(std::exception& e) {
- log_warning << "Couldn't load console.nut: " << e.what() << std::endl;
- }
- }
-}
-
-void
-Console::execute_script(const std::string& command)
-{
- using namespace Scripting;
-
- ready_vm();
-
- SQInteger oldtop = sq_gettop(vm);
- try {
- if(SQ_FAILED(sq_compilebuffer(vm, command.c_str(), command.length(),
- "", SQTrue)))
- throw SquirrelError(vm, "Couldn't compile command");
-
- sq_pushroottable(vm);
- if(SQ_FAILED(sq_call(vm, 1, SQTrue, SQTrue)))
- throw SquirrelError(vm, "Problem while executing command");
-
- if(sq_gettype(vm, -1) != OT_NULL)
- addLines(squirrel2string(vm, -1));
- } catch(std::exception& e) {
- addLines(e.what());
- }
- SQInteger newtop = sq_gettop(vm);
- if(newtop < oldtop) {
- log_fatal << "Script destroyed squirrel stack..." << std::endl;
- } else {
- sq_settop(vm, oldtop);
- }
-}
-
-void
-Console::input(char c)
-{
- inputBuffer.insert(inputBufferPosition, 1, c);
- inputBufferPosition++;
-}
-
-void
-Console::backspace()
-{
- if ((inputBufferPosition > 0) && (inputBuffer.length() > 0)) {
- inputBuffer.erase(inputBufferPosition-1, 1);
- inputBufferPosition--;
- }
-}
-
-void
-Console::eraseChar()
-{
- if (inputBufferPosition < (int)inputBuffer.length()) {
- inputBuffer.erase(inputBufferPosition, 1);
- }
-}
-
-void
-Console::enter()
-{
- addLines("> "+inputBuffer);
- parse(inputBuffer);
- inputBuffer = "";
- inputBufferPosition = 0;
-}
-
-void
-Console::scroll(int numLines)
-{
- offset += numLines;
- if (offset > 0) offset = 0;
-}
-
-void
-Console::show_history(int offset)
-{
- while ((offset > 0) && (history_position != history.end())) {
- history_position++;
- offset--;
- }
- while ((offset < 0) && (history_position != history.begin())) {
- history_position--;
- offset++;
- }
- if (history_position == history.end()) {
- inputBuffer = "";
- inputBufferPosition = 0;
- } else {
- inputBuffer = *history_position;
- inputBufferPosition = inputBuffer.length();
- }
-}
-
-void
-Console::move_cursor(int offset)
-{
- if (offset == -65535) inputBufferPosition = 0;
- if (offset == +65535) inputBufferPosition = inputBuffer.length();
- inputBufferPosition+=offset;
- if (inputBufferPosition < 0) inputBufferPosition = 0;
- if (inputBufferPosition > (int)inputBuffer.length()) inputBufferPosition = inputBuffer.length();
-}
-
-// Helper functions for Console::autocomplete
-// TODO: Fix rough documentation
-namespace {
-
-void sq_insert_commands(std::list<std::string>& cmds, HSQUIRRELVM vm, std::string table_prefix, std::string search_prefix);
-
-/**
- * Acts upon key,value on top of stack:
- * Appends key (plus type-dependent suffix) to cmds if table_prefix+key starts with search_prefix;
- * Calls sq_insert_commands if search_prefix starts with table_prefix+key (and value is a table/class/instance);
- */
-void
-sq_insert_command(std::list<std::string>& cmds, HSQUIRRELVM vm, std::string table_prefix, std::string search_prefix)
-{
- const SQChar* key_chars;
- if (SQ_FAILED(sq_getstring(vm, -2, &key_chars))) return;
- std::string key_string = table_prefix + key_chars;
-
- switch (sq_gettype(vm, -1)) {
- case OT_INSTANCE:
- key_string+=".";
- if (search_prefix.substr(0, key_string.length()) == key_string) {
- sq_getclass(vm, -1);
- sq_insert_commands(cmds, vm, key_string, search_prefix);
- sq_pop(vm, 1);
- }
- break;
- case OT_TABLE:
- case OT_CLASS:
- key_string+=".";
- if (search_prefix.substr(0, key_string.length()) == key_string) {
- sq_insert_commands(cmds, vm, key_string, search_prefix);
- }
- break;
- case OT_CLOSURE:
- case OT_NATIVECLOSURE:
- key_string+="()";
- break;
- default:
- break;
- }
-
- if (key_string.substr(0, search_prefix.length()) == search_prefix) {
- cmds.push_back(key_string);
- }
-
-}
-
-/**
- * calls sq_insert_command for all entries of table/class on top of stack
- */
-void
-sq_insert_commands(std::list<std::string>& cmds, HSQUIRRELVM vm, std::string table_prefix, std::string search_prefix)
-{
- sq_pushnull(vm); // push iterator
- while (SQ_SUCCEEDED(sq_next(vm,-2))) {
- sq_insert_command(cmds, vm, table_prefix, search_prefix);
- sq_pop(vm, 2); // pop key, val
- }
- sq_pop(vm, 1); // pop iterator
-}
-
-
-}
-// End of Console::autocomplete helper functions
-
-void
-Console::autocomplete()
-{
- //int autocompleteFrom = inputBuffer.find_last_of(" ();+", inputBufferPosition);
- int autocompleteFrom = inputBuffer.find_last_not_of("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_->.", inputBufferPosition);
- if (autocompleteFrom != (int)std::string::npos) {
- autocompleteFrom += 1;
- } else {
- autocompleteFrom = 0;
- }
- std::string prefix = inputBuffer.substr(autocompleteFrom, inputBufferPosition - autocompleteFrom);
- addLines("> "+prefix);
-
- std::list<std::string> cmds;
-
- ready_vm();
-
- // append all keys of the current root table to list
- sq_pushroottable(vm); // push root table
- while(true) {
- // check all keys (and their children) for matches
- sq_insert_commands(cmds, vm, "", prefix);
-
- // cycle through parent(delegate) table
- SQInteger oldtop = sq_gettop(vm);
- if(SQ_FAILED(sq_getdelegate(vm, -1)) || oldtop == sq_gettop(vm)) {
- break;
- }
- sq_remove(vm, -2); // remove old table
- }
- sq_pop(vm, 1); // remove table
-
- // depending on number of hits, show matches or autocomplete
- if (cmds.size() == 0) addLines("No known command starts with \""+prefix+"\"");
- if (cmds.size() == 1) {
- // one match: just replace input buffer with full command
- std::string replaceWith = cmds.front();
- inputBuffer.replace(autocompleteFrom, prefix.length(), replaceWith);
- inputBufferPosition += (replaceWith.length() - prefix.length());
- }
- if (cmds.size() > 1) {
- // multiple matches: show all matches and set input buffer to longest common prefix
- std::string commonPrefix = cmds.front();
- while (cmds.begin() != cmds.end()) {
- std::string cmd = cmds.front();
- cmds.pop_front();
- addLines(cmd);
- for (int n = commonPrefix.length(); n >= 1; n--) {
- if (cmd.compare(0, n, commonPrefix) != 0) commonPrefix.resize(n-1); else break;
- }
- }
- std::string replaceWith = commonPrefix;
- inputBuffer.replace(autocompleteFrom, prefix.length(), replaceWith);
- inputBufferPosition += (replaceWith.length() - prefix.length());
- }
-}
-
-void
-Console::addLines(std::string s)
-{
- std::istringstream iss(s);
- std::string line;
- while (std::getline(iss, line, '\n')) addLine(line);
-}
-
-void
-Console::addLine(std::string s)
-{
- // output line to stderr
- std::cerr << s << std::endl;
-
- // wrap long lines
- std::string overflow;
- unsigned int line_count = 0;
- do {
- lines.push_front(Font::wrap_to_chars(s, 99, &overflow));
- line_count++;
- s = overflow;
- } while (s.length() > 0);
-
- // trim scrollback buffer
- while (lines.size() >= 1000)
- lines.pop_back();
-
- // increase console height if necessary
- if (height < 64) {
- if(height < 4)
- height = 4;
- height += fontheight * line_count;
- }
-
- // reset console to full opacity
- alpha = 1.0;
-
- // increase time that console stays open
- if(stayOpen < 6)
- stayOpen += 1.5;
-}
-
-void
-Console::parse(std::string s)
-{
- // make sure we actually have something to parse
- if (s.length() == 0) return;
-
- // add line to history
- history.push_back(s);
- history_position = history.end();
-
- // split line into list of args
- std::vector<std::string> args;
- size_t start = 0;
- size_t end = 0;
- while (1) {
- start = s.find_first_not_of(" ,", end);
- end = s.find_first_of(" ,", start);
- if (start == s.npos) break;
- args.push_back(s.substr(start, end-start));
- }
-
- // command is args[0]
- if (args.size() == 0) return;
- std::string command = args.front();
- args.erase(args.begin());
-
- // ignore if it's an internal command
- if (consoleCommand(command,args)) return;
-
- try {
- execute_script(s);
- } catch(std::exception& e) {
- addLines(e.what());
- }
-
-}
-
-bool
-Console::consoleCommand(std::string /*command*/, std::vector<std::string> /*arguments*/)
-{
- return false;
-}
-
-bool
-Console::hasFocus()
-{
- return focused;
-}
-
-void
-Console::show()
-{
- if(!config->console_enabled)
- return;
-
- focused = true;
- height = 256;
- alpha = 1.0;
- SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
-}
-
-void
-Console::hide()
-{
- focused = false;
- height = 0;
- stayOpen = 0;
-
- // clear input buffer
- inputBuffer = "";
- inputBufferPosition = 0;
- SDL_EnableKeyRepeat(0, SDL_DEFAULT_REPEAT_INTERVAL);
-}
-
-void
-Console::toggle()
-{
- if (Console::hasFocus()) {
- Console::hide();
- }
- else {
- Console::show();
- }
-}
-
-void
-Console::update(float elapsed_time)
-{
- if(stayOpen > 0) {
- stayOpen -= elapsed_time;
- if(stayOpen < 0)
- stayOpen = 0;
- } else if(!focused && height > 0) {
- alpha -= elapsed_time * FADE_SPEED;
- if(alpha < 0) {
- alpha = 0;
- height = 0;
- }
- }
-}
-
-void
-Console::draw(DrawingContext& context)
-{
- if (height == 0)
- return;
-
- int layer = LAYER_GUI + 1;
-
- context.push_transform();
- context.set_alpha(alpha);
- context.draw_surface(background2.get(), Vector(SCREEN_WIDTH/2 - background->get_width()/2 - background->get_width() + backgroundOffset, height - background->get_height()), layer);
- context.draw_surface(background2.get(), Vector(SCREEN_WIDTH/2 - background->get_width()/2 + backgroundOffset, height - background->get_height()), layer);
- for (int x = (SCREEN_WIDTH/2 - background->get_width()/2 - (static_cast<int>(ceilf((float)SCREEN_WIDTH / (float)background->get_width()) - 1) * background->get_width())); x < SCREEN_WIDTH; x+=background->get_width()) {
- context.draw_surface(background.get(), Vector(x, height - background->get_height()), layer);
- }
- backgroundOffset+=10;
- if (backgroundOffset > (int)background->get_width()) backgroundOffset -= (int)background->get_width();
-
- int lineNo = 0;
-
- if (focused) {
- lineNo++;
- float py = height-4-1 * font->get_height();
- context.draw_text(font.get(), "> "+inputBuffer, Vector(4, py), ALIGN_LEFT, layer);
- if (SDL_GetTicks() % 1000 < 750) {
- int cursor_px = 2 + inputBufferPosition;
- context.draw_text(font.get(), "_", Vector(4 + (cursor_px * font->get_text_width("X")), py), ALIGN_LEFT, layer);
- }
- }
-
- int skipLines = -offset;
- for (std::list<std::string>::iterator i = lines.begin(); i != lines.end(); i++) {
- if (skipLines-- > 0) continue;
- lineNo++;
- float py = height - 4 - lineNo*font->get_height();
- if (py < -font->get_height()) break;
- context.draw_text(font.get(), *i, Vector(4, py), ALIGN_LEFT, layer);
- }
- context.pop_transform();
-}
-
-Console* Console::instance = NULL;
-int Console::inputBufferPosition = 0;
-std::string Console::inputBuffer;
-ConsoleStreamBuffer Console::outputBuffer;
-std::ostream Console::output(&Console::outputBuffer);
-
+++ /dev/null
-// $Id$
-//
-// SuperTux - Console
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#ifndef SUPERTUX_CONSOLE_H
-#define SUPERTUX_CONSOLE_H
-
-#include <list>
-#include <map>
-#include <vector>
-#include <string>
-#include <sstream>
-#include <iostream>
-#include <memory>
-#include <squirrel.h>
-
-class Console;
-class ConsoleStreamBuffer;
-class ConsoleCommandReceiver;
-class DrawingContext;
-class Surface;
-class Font;
-
-class Console
-{
-public:
- Console();
- ~Console();
-
- static Console* instance;
-
- static std::ostream output; /**< stream of characters to output to the console. Do not forget to send std::endl or to flush the stream. */
-
- void init_graphics();
-
- void input(char c); /**< add character to inputBuffer */
- void backspace(); /**< delete character left of inputBufferPosition */
- void eraseChar(); /**< delete character at inputBufferPosition */
- void enter(); /**< process and clear input stream */
- void scroll(int offset); /**< scroll console text up or down by @c offset lines */
- void autocomplete(); /**< autocomplete current command */
- void show_history(int offset); /**< move @c offset lines forward through history; Negative offset moves backward */
- void move_cursor(int offset); /**< move the cursor @c offset chars to the right; Negative offset moves backward; 0xFFFF moves to the end */
-
- void draw(DrawingContext& context); /**< draw the console in a DrawingContext */
- void update(float elapsed_time);
-
- void show(); /**< display the console */
- void hide(); /**< hide the console */
- void toggle(); /**< display the console if hidden, hide otherwise */
-
- bool hasFocus(); /**< true if characters should be sent to the console instead of their normal target */
-
- template<typename T> static bool string_is(std::string s) {
- std::istringstream iss(s);
- T i;
- if ((iss >> i) && iss.eof()) {
- return true;
- } else {
- return false;
- }
- }
-
- template<typename T> static T string_to(std::string s) {
- std::istringstream iss(s);
- T i;
- if ((iss >> i) && iss.eof()) {
- return i;
- } else {
- return T();
- }
- }
-
-private:
- std::list<std::string> history; /**< command history. New lines get added to back. */
- std::list<std::string>::iterator history_position; /**< item of command history that is currently displayed */
- std::list<std::string> lines; /**< backbuffer of lines sent to the console. New lines get added to front. */
-
- std::auto_ptr<Surface> background; /**< console background image */
- std::auto_ptr<Surface> background2; /**< second, moving console background image */
-
- HSQUIRRELVM vm; /**< squirrel thread for the console (with custom roottable) */
- HSQOBJECT vm_object;
-
- int backgroundOffset; /**< current offset of scrolling background image */
- float height; /**< height of the console in px */
- float alpha;
- int offset; /**< decrease to scroll text up */
- bool focused; /**< true if console has input focus */
- std::auto_ptr<Font> font;
- float fontheight; /**< height of the font (this is a separate var, because the font could not be initialized yet but is needed in the addLine message */
-
- float stayOpen;
-
- static int inputBufferPosition; /**< position in inputBuffer before which to append new characters */
- static std::string inputBuffer; /**< string used for keyboard input */
- static ConsoleStreamBuffer outputBuffer; /**< stream buffer used by output stream */
-
- void addLines(std::string s); /**< display a string of (potentially) multiple lines in the console */
- void addLine(std::string s); /**< display a line in the console */
- void parse(std::string s); /**< react to a given command */
-
- /** ready a virtual machine instance, creating a new thread and loading default .nut files if needed */
- void ready_vm();
-
- /** execute squirrel script and output result */
- void execute_script(const std::string& s);
-
- bool consoleCommand(std::string command, std::vector<std::string> arguments); /**< process internal command; return false if command was unknown, true otherwise */
-
- friend class ConsoleStreamBuffer;
- void flush(ConsoleStreamBuffer* buffer); /**< act upon changes in a ConsoleStreamBuffer */
-};
-
-class ConsoleStreamBuffer : public std::stringbuf
-{
- public:
- int sync()
- {
- int result = std::stringbuf::sync();
- if(Console::instance != NULL)
- Console::instance->flush(this);
- return result;
- }
-};
-
-#endif
+++ /dev/null
-// $Id: world.hpp 4063 2006-07-21 21:05:23Z anmaster $
-//
-// SuperTux
-// Copyright (C) 2009 Mathnerd314
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#ifndef SUPERTUX_CONSTANTS_HPP
-#define SUPERTUX_CONSTANTS_HPP
-
-//Useful constants
-
-// a small value... be careful as CD is very sensitive to it
-static const float DELTA = .0005f;
-
-// the engine will be run with a logical framerate of 64fps.
-// We chose 64fps here because it is a power of 2, so 1/64 gives an "even"
-// binary fraction...
-static const float LOGICAL_FPS = 64.0;
-
-// SHIFT_DELTA is used for sliding over 1-tile gaps and collision detection
-static const float SHIFT_DELTA = 7.0f;
-
-#endif
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "codecontroller.hpp"
+#include "control/codecontroller.hpp"
CodeController::CodeController()
{}
for(int i = 0; i < CONTROLCOUNT; ++i)
controls[i] = false;
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __CODECONTROLLER_H__
-#define __CODECONTROLLER_H__
+#ifndef HEADER_SUPERTUX_CONTROL_CODECONTROLLER_HPP
+#define HEADER_SUPERTUX_CONTROL_CODECONTROLLER_HPP
-#include "controller.hpp"
+#include "control/controller.hpp"
/**
* This is a dummy controller that doesn't react to any user input but should
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "controller.hpp"
+#include "control/controller.hpp"
const char* Controller::controlNames[] = {
"left",
for(int i = 0; i < CONTROLCOUNT; ++i)
oldControls[i] = controls[i];
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __CONTROLLER_H__
-#define __CONTROLLER_H__
+#ifndef HEADER_SUPERTUX_CONTROL_CONTROLLER_HPP
+#define HEADER_SUPERTUX_CONTROL_CONTROLLER_HPP
class Controller
{
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>,
// 2007 Ingo Ruhnke <grumbel@gmx.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "joystickkeyboardcontroller.hpp"
+#include "control/joystickkeyboardcontroller.hpp"
-#include <sstream>
+#include <iostream>
-#include "log.hpp"
#include "gui/menu.hpp"
-#include "gettext.hpp"
-#include "lisp/writer.hpp"
-#include "lisp/lisp.hpp"
+#include "util/writer.hpp"
#include "lisp/list_iterator.hpp"
-#include "game_session.hpp"
-#include "console.hpp"
-#include "gameconfig.hpp"
+#include "supertux/gameconfig.hpp"
+#include "supertux/console.hpp"
+#include "util/gettext.hpp"
namespace{
const int SCAN_JOYSTICKS = Controller::CONTROLCOUNT + 1;
}
void
-JoystickKeyboardController::read(const lisp::Lisp& lisp)
+JoystickKeyboardController::read(const Reader& lisp)
{
const lisp::Lisp* keymap_lisp = lisp.get_lisp("keymap");
if(keymap_lisp) {
}
void
-JoystickKeyboardController::write(lisp::Writer& writer)
+JoystickKeyboardController::write(Writer& writer)
{
writer.start_list("keymap");
writer.write("jump-with-up", jump_with_up_kbd);
JoystickKeyboardController::process_button_event(const SDL_JoyButtonEvent& jbutton)
{
if(wait_for_joystick >= 0)
+ {
+ if(jbutton.state == SDL_PRESSED)
{
- if(jbutton.state == SDL_PRESSED)
- {
- bind_joybutton(jbutton.button, (Control)wait_for_joystick);
- joystick_options_menu->update();
- reset();
- wait_for_joystick = -1;
- }
- }
+ bind_joybutton(jbutton.button, (Control)wait_for_joystick);
+ joystick_options_menu->update();
+ reset();
+ wait_for_joystick = -1;
+ }
+ }
else
- {
- ButtonMap::iterator i = joy_button_map.find(jbutton.button);
- if(i == joy_button_map.end()) {
- log_debug << "Unmapped joybutton " << (int)jbutton.button << " pressed" << std::endl;
- } else {
- set_joy_controls(i->second, (jbutton.state == SDL_PRESSED));
- }
+ {
+ ButtonMap::iterator i = joy_button_map.find(jbutton.button);
+ if(i == joy_button_map.end()) {
+ log_debug << "Unmapped joybutton " << (int)jbutton.button << " pressed" << std::endl;
+ } else {
+ set_joy_controls(i->second, (jbutton.state == SDL_PRESSED));
}
+ }
}
void
JoystickKeyboardController::process_axis_event(const SDL_JoyAxisEvent& jaxis)
{
if (wait_for_joystick >= 0)
- {
- if (abs(jaxis.value) > dead_zone) {
- if (jaxis.value < 0)
- bind_joyaxis(-(jaxis.axis + 1), Control(wait_for_joystick));
- else
- bind_joyaxis(jaxis.axis + 1, Control(wait_for_joystick));
-
- joystick_options_menu->update();
- wait_for_joystick = -1;
- }
+ {
+ if (abs(jaxis.value) > dead_zone) {
+ if (jaxis.value < 0)
+ bind_joyaxis(-(jaxis.axis + 1), Control(wait_for_joystick));
+ else
+ bind_joyaxis(jaxis.axis + 1, Control(wait_for_joystick));
+
+ joystick_options_menu->update();
+ wait_for_joystick = -1;
}
+ }
else
- {
- // Split the axis into left and right, so that both can be
- // mapped separately (needed for jump/down vs up/down)
- int axis = jaxis.axis + 1;
-
- AxisMap::iterator left = joy_axis_map.find(-axis);
- AxisMap::iterator right = joy_axis_map.find(axis);
-
- if(left == joy_axis_map.end()) {
- std::cout << "Unmapped joyaxis " << (int)jaxis.axis << " moved" << std::endl;
- } else {
- if (jaxis.value < -dead_zone)
- set_joy_controls(left->second, true);
- else if (jaxis.value > dead_zone)
- set_joy_controls(left->second, false);
- else
- set_joy_controls(left->second, false);
- }
+ {
+ // Split the axis into left and right, so that both can be
+ // mapped separately (needed for jump/down vs up/down)
+ int axis = jaxis.axis + 1;
- if(right == joy_axis_map.end()) {
- std::cout << "Unmapped joyaxis " << (int)jaxis.axis << " moved" << std::endl;
- } else {
- if (jaxis.value < -dead_zone)
- set_joy_controls(right->second, false);
- else if (jaxis.value > dead_zone)
- set_joy_controls(right->second, true);
- else
- set_joy_controls(right->second, false);
- }
+ AxisMap::iterator left = joy_axis_map.find(-axis);
+ AxisMap::iterator right = joy_axis_map.find(axis);
+
+ if(left == joy_axis_map.end()) {
+ std::cout << "Unmapped joyaxis " << (int)jaxis.axis << " moved" << std::endl;
+ } else {
+ if (jaxis.value < -dead_zone)
+ set_joy_controls(left->second, true);
+ else if (jaxis.value > dead_zone)
+ set_joy_controls(left->second, false);
+ else
+ set_joy_controls(left->second, false);
+ }
+
+ if(right == joy_axis_map.end()) {
+ std::cout << "Unmapped joyaxis " << (int)jaxis.axis << " moved" << std::endl;
+ } else {
+ if (jaxis.value < -dead_zone)
+ set_joy_controls(right->second, false);
+ else if (jaxis.value > dead_zone)
+ set_joy_controls(right->second, true);
+ else
+ set_joy_controls(right->second, false);
}
+ }
}
void
Uint8 changed = hat_state ^ jhat.value;
if (wait_for_joystick >= 0)
- {
- if (changed & SDL_HAT_UP && jhat.value & SDL_HAT_UP)
- bind_joyhat(SDL_HAT_UP, (Control)wait_for_joystick);
+ {
+ if (changed & SDL_HAT_UP && jhat.value & SDL_HAT_UP)
+ bind_joyhat(SDL_HAT_UP, (Control)wait_for_joystick);
- if (changed & SDL_HAT_DOWN && jhat.value & SDL_HAT_DOWN)
- bind_joyhat(SDL_HAT_DOWN, (Control)wait_for_joystick);
+ if (changed & SDL_HAT_DOWN && jhat.value & SDL_HAT_DOWN)
+ bind_joyhat(SDL_HAT_DOWN, (Control)wait_for_joystick);
- if (changed & SDL_HAT_LEFT && jhat.value & SDL_HAT_LEFT)
- bind_joyhat(SDL_HAT_LEFT, (Control)wait_for_joystick);
+ if (changed & SDL_HAT_LEFT && jhat.value & SDL_HAT_LEFT)
+ bind_joyhat(SDL_HAT_LEFT, (Control)wait_for_joystick);
- if (changed & SDL_HAT_RIGHT && jhat.value & SDL_HAT_RIGHT)
- bind_joyhat(SDL_HAT_RIGHT, (Control)wait_for_joystick);
+ if (changed & SDL_HAT_RIGHT && jhat.value & SDL_HAT_RIGHT)
+ bind_joyhat(SDL_HAT_RIGHT, (Control)wait_for_joystick);
- joystick_options_menu->update();
- wait_for_joystick = -1;
- }
+ joystick_options_menu->update();
+ wait_for_joystick = -1;
+ }
else
+ {
+ if (changed & SDL_HAT_UP)
{
- if (changed & SDL_HAT_UP)
- {
- HatMap::iterator it = joy_hat_map.find(SDL_HAT_UP);
- if (it != joy_hat_map.end())
- set_joy_controls(it->second, jhat.value & SDL_HAT_UP);
- }
+ HatMap::iterator it = joy_hat_map.find(SDL_HAT_UP);
+ if (it != joy_hat_map.end())
+ set_joy_controls(it->second, jhat.value & SDL_HAT_UP);
+ }
- if (changed & SDL_HAT_DOWN)
- {
- HatMap::iterator it = joy_hat_map.find(SDL_HAT_DOWN);
- if (it != joy_hat_map.end())
- set_joy_controls(it->second, jhat.value & SDL_HAT_DOWN);
- }
+ if (changed & SDL_HAT_DOWN)
+ {
+ HatMap::iterator it = joy_hat_map.find(SDL_HAT_DOWN);
+ if (it != joy_hat_map.end())
+ set_joy_controls(it->second, jhat.value & SDL_HAT_DOWN);
+ }
- if (changed & SDL_HAT_LEFT)
- {
- HatMap::iterator it = joy_hat_map.find(SDL_HAT_LEFT);
- if (it != joy_hat_map.end())
- set_joy_controls(it->second, jhat.value & SDL_HAT_LEFT);
- }
+ if (changed & SDL_HAT_LEFT)
+ {
+ HatMap::iterator it = joy_hat_map.find(SDL_HAT_LEFT);
+ if (it != joy_hat_map.end())
+ set_joy_controls(it->second, jhat.value & SDL_HAT_LEFT);
+ }
- if (changed & SDL_HAT_RIGHT)
- {
- HatMap::iterator it = joy_hat_map.find(SDL_HAT_RIGHT);
- if (it != joy_hat_map.end())
- set_joy_controls(it->second, jhat.value & SDL_HAT_RIGHT);
- }
+ if (changed & SDL_HAT_RIGHT)
+ {
+ HatMap::iterator it = joy_hat_map.find(SDL_HAT_RIGHT);
+ if (it != joy_hat_map.end())
+ set_joy_controls(it->second, jhat.value & SDL_HAT_RIGHT);
}
+ }
hat_state = jhat.value;
}
return;
if(event.key.keysym.sym != SDLK_ESCAPE
- && event.key.keysym.sym != SDLK_PAUSE) {
+ && event.key.keysym.sym != SDLK_PAUSE) {
bind_key(event.key.keysym.sym, (Control) wait_for_key);
}
reset();
//----------------------------------------------------------------------------
JoystickKeyboardController::KeyboardMenu::KeyboardMenu(
- JoystickKeyboardController* _controller)
+ JoystickKeyboardController* _controller)
: controller(_controller)
{
- add_label(_("Setup Keyboard"));
- add_hl();
- add_controlfield(Controller::UP, _("Up"));
- add_controlfield(Controller::DOWN, _("Down"));
- add_controlfield(Controller::LEFT, _("Left"));
- add_controlfield(Controller::RIGHT, _("Right"));
- add_controlfield(Controller::JUMP, _("Jump"));
- add_controlfield(Controller::ACTION, _("Action"));
- add_controlfield(Controller::PEEK_LEFT, _("Peek Left"));
- add_controlfield(Controller::PEEK_RIGHT, _("Peek Right"));
- add_controlfield(Controller::PEEK_UP, _("Peek Up"));
- add_controlfield(Controller::PEEK_DOWN, _("Peek Down"));
- if (config->console_enabled) {
- add_controlfield(Controller::CONSOLE, _("Console"));
- }
- add_toggle(Controller::CONTROLCOUNT, _("Jump with Up"), controller->jump_with_up_kbd);
- add_hl();
- add_back(_("Back"));
- update();
+ add_label(_("Setup Keyboard"));
+ add_hl();
+ add_controlfield(Controller::UP, _("Up"));
+ add_controlfield(Controller::DOWN, _("Down"));
+ add_controlfield(Controller::LEFT, _("Left"));
+ add_controlfield(Controller::RIGHT, _("Right"));
+ add_controlfield(Controller::JUMP, _("Jump"));
+ add_controlfield(Controller::ACTION, _("Action"));
+ add_controlfield(Controller::PEEK_LEFT, _("Peek Left"));
+ add_controlfield(Controller::PEEK_RIGHT, _("Peek Right"));
+ add_controlfield(Controller::PEEK_UP, _("Peek Up"));
+ add_controlfield(Controller::PEEK_DOWN, _("Peek Down"));
+ if (g_config->console_enabled) {
+ add_controlfield(Controller::CONSOLE, _("Console"));
+ }
+ add_toggle(Controller::CONTROLCOUNT, _("Jump with Up"), controller->jump_with_up_kbd);
+ add_hl();
+ add_back(_("Back"));
+ update();
}
JoystickKeyboardController::KeyboardMenu::~KeyboardMenu()
{
// update menu
get_item_by_id((int) Controller::UP).change_input(get_key_name(
- controller->reversemap_key(Controller::UP)));
+ controller->reversemap_key(Controller::UP)));
get_item_by_id((int) Controller::DOWN).change_input(get_key_name(
- controller->reversemap_key(Controller::DOWN)));
+ controller->reversemap_key(Controller::DOWN)));
get_item_by_id((int) Controller::LEFT).change_input(get_key_name(
- controller->reversemap_key(Controller::LEFT)));
+ controller->reversemap_key(Controller::LEFT)));
get_item_by_id((int) Controller::RIGHT).change_input(get_key_name(
- controller->reversemap_key(Controller::RIGHT)));
+ controller->reversemap_key(Controller::RIGHT)));
get_item_by_id((int) Controller::JUMP).change_input(get_key_name(
- controller->reversemap_key(Controller::JUMP)));
+ controller->reversemap_key(Controller::JUMP)));
get_item_by_id((int) Controller::ACTION).change_input(get_key_name(
- controller->reversemap_key(Controller::ACTION)));
+ controller->reversemap_key(Controller::ACTION)));
get_item_by_id((int) Controller::PEEK_LEFT).change_input(get_key_name(
- controller->reversemap_key(Controller::PEEK_LEFT)));
+ controller->reversemap_key(Controller::PEEK_LEFT)));
get_item_by_id((int) Controller::PEEK_RIGHT).change_input(get_key_name(
- controller->reversemap_key(Controller::PEEK_RIGHT)));
+ controller->reversemap_key(Controller::PEEK_RIGHT)));
get_item_by_id((int) Controller::PEEK_UP).change_input(get_key_name(
- controller->reversemap_key(Controller::PEEK_UP)));
+ controller->reversemap_key(Controller::PEEK_UP)));
get_item_by_id((int) Controller::PEEK_DOWN).change_input(get_key_name(
- controller->reversemap_key(Controller::PEEK_DOWN)));
- if (config->console_enabled) {
+ controller->reversemap_key(Controller::PEEK_DOWN)));
+ if (g_config->console_enabled) {
get_item_by_id((int) Controller::CONSOLE).change_input(get_key_name(
- controller->reversemap_key(Controller::CONSOLE)));
+ controller->reversemap_key(Controller::CONSOLE)));
}
get_item_by_id(Controller::CONTROLCOUNT).toggled = controller->jump_with_up_kbd;
}
std::string name;
switch (hat_dir)
- {
- case SDL_HAT_UP:
- name = "Hat Up";
- break;
-
- case SDL_HAT_DOWN:
- name = "Hat Down";
- break;
-
- case SDL_HAT_LEFT:
- name = "Hat Left";
- break;
-
- case SDL_HAT_RIGHT:
- name = "Hat Right";
- break;
-
- default:
- name = "Unknown hat_dir";
- break;
- }
+ {
+ case SDL_HAT_UP:
+ name = "Hat Up";
+ break;
+
+ case SDL_HAT_DOWN:
+ name = "Hat Down";
+ break;
+
+ case SDL_HAT_LEFT:
+ name = "Hat Left";
+ break;
+
+ case SDL_HAT_RIGHT:
+ name = "Hat Right";
+ break;
+
+ default:
+ name = "Unknown hat_dir";
+ break;
+ }
get_item_by_id((int)id).change_input(name);
} else {
get_item_by_id(Controller::CONTROLCOUNT).toggled = controller->jump_with_up_joy;
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#ifndef __JOYSTICKKEYBOARDCONTROLLER_H__
-#define __JOYSTICKKEYBOARDCONTROLLER_H__
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "controller.hpp"
+#ifndef HEADER_SUPERTUX_CONTROL_JOYSTICKKEYBOARDCONTROLLER_HPP
+#define HEADER_SUPERTUX_CONTROL_JOYSTICKKEYBOARDCONTROLLER_HPP
-namespace lisp {
-class Writer;
-class Lisp;
-}
+#include "control/controller.hpp"
#include <SDL.h>
-#include <string>
#include <map>
+#include <string>
#include <vector>
+#include "util/reader_fwd.hpp"
+#include "util/writer_fwd.hpp"
+
class Menu;
class JoystickKeyboardController : public Controller
void process_event(const SDL_Event& event);
void write(lisp::Writer& writer);
- void read(const lisp::Lisp& lisp);
+ void read(const Reader& lisp);
void reset();
Menu* get_key_options_menu();
JoystickMenu* joystick_options_menu;
friend class KeyboardMenu;
friend class JoystickMenu;
+
+private:
+ JoystickKeyboardController(const JoystickKeyboardController&);
+ JoystickKeyboardController& operator=(const JoystickKeyboardController&);
};
#endif
+
+/* EOF */
+++ /dev/null
-// $Id: direction.hpp 5006 2007-05-23 15:27:56Z tuxdev $
-//
-// SuperTux
-// Copyright (C) 2008 Ryan Flegel <rflegel@gmail.com>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-
-#include "direction.hpp"
-
-std::ostream& operator<<(std::ostream& o, const Direction& dir)
-{
- switch (dir)
- {
- case AUTO:
- o << "auto";
- break;
- case LEFT:
- o << "left";
- break;
- case RIGHT:
- o << "right";
- break;
- case UP:
- o << "up";
- break;
- case DOWN:
- o << "down";
- break;
- }
-
- return o;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-#ifndef SUPERTUX_DIRECTION_H
-#define SUPERTUX_DIRECTION_H
-
-#include <iostream>
-
-enum Direction { AUTO, LEFT, RIGHT, UP, DOWN };
-
-std::ostream& operator<<(std::ostream& o, const Direction& dir);
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include <config.h>
-
-#include "fadeout.hpp"
-#include "main.hpp"
-#include "video/drawing_context.hpp"
-
-FadeOut::FadeOut(float fade_time, Color color)
- : color(color), fade_time(fade_time), accum_time(0)
-{
-}
-
-FadeOut::~FadeOut()
-{
-}
-
-void
-FadeOut::update(float elapsed_time)
-{
- accum_time += elapsed_time;
- if(accum_time > fade_time)
- accum_time = fade_time;
-}
-
-void
-FadeOut::draw(DrawingContext& context)
-{
- Color col = color;
- col.alpha = accum_time / fade_time;
- context.draw_filled_rect(Vector(0, 0),
- Vector(SCREEN_WIDTH, SCREEN_HEIGHT),
- col, LAYER_GUI+1);
-}
-
-bool
-FadeOut::done()
-{
- return accum_time >= fade_time;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#ifndef __FADEOUT_HPP__
-#define __FADEOUT_HPP__
-
-#include "video/color.hpp"
-#include "screen_fade.hpp"
-
-/**
- * Fades a screen towards a specific color
- */
-class FadeOut : public ScreenFade
-{
-public:
- FadeOut(float fade_time, Color dest_color = Color(0, 0, 0));
- virtual ~FadeOut();
-
- virtual void update(float elapsed_time);
- virtual void draw(DrawingContext& context);
-
- /// returns true if the effect is completed
- virtual bool done();
-
-private:
- Color color;
- float fade_time;
- float accum_time;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
-
-#include "log.hpp"
-#include "file_system.hpp"
-
-#include <string>
-#include <vector>
-#include <sstream>
-
-namespace FileSystem
-{
-
-std::string dirname(const std::string& filename)
-{
- std::string::size_type p = filename.find_last_of('/');
- if(p == std::string::npos)
- p = filename.find_last_of('\\');
- if(p == std::string::npos)
- return "./";
-
- return filename.substr(0, p+1);
-}
-
-std::string basename(const std::string& filename)
-{
- std::string::size_type p = filename.find_last_of('/');
- if(p == std::string::npos)
- p = filename.find_last_of('\\');
- if(p == std::string::npos)
- return filename;
-
- return filename.substr(p+1, filename.size()-p-1);
-}
-
-std::string strip_extension(const std::string& filename)
-{
- std::string::size_type p = filename.find_last_of('.');
- if(p == std::string::npos)
- return filename;
-
- return filename.substr(0, p);
-}
-
-std::string normalize(const std::string& filename)
-{
- std::vector<std::string> path_stack;
-
- const char* p = filename.c_str();
-
- while(true) {
- while(*p == '/' || *p == '\\') {
- p++;
- continue;
- }
-
- const char* pstart = p;
- while(*p != '/' && *p != '\\' && *p != 0) {
- ++p;
- }
-
- size_t len = p - pstart;
- if(len == 0)
- break;
-
- std::string pathelem(pstart, p-pstart);
- if(pathelem == ".")
- continue;
-
- if(pathelem == "..") {
- if(path_stack.empty()) {
-
- log_warning << "Invalid '..' in path '" << filename << "'" << std::endl;
- // push it into the result path so that the user sees his error...
- path_stack.push_back(pathelem);
- } else {
- path_stack.pop_back();
- }
- } else {
- path_stack.push_back(pathelem);
- }
- }
-
- // construct path
- std::ostringstream result;
- for(std::vector<std::string>::iterator i = path_stack.begin();
- i != path_stack.end(); ++i) {
- result << '/' << *i;
- }
- if(path_stack.empty())
- result << '/';
-
- return result.str();
-}
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#ifndef __FILESYSTEM_H__
-#define __FILESYSTEM_H__
-
-#include <set>
-#include <string>
-
-namespace FileSystem
-{
- /**
- * returns the path of the directory the file is in
- */
- std::string dirname(const std::string& filename);
-
- /**
- * returns the name of the file
- */
- std::string basename(const std::string& filename);
-
- /**
- * remove everything starting from and including the last dot
- */
- std::string strip_extension(const std::string& filename);
-
- /**
- * normalize filename so that "blup/bla/blo/../../bar" will become
- * "blup/bar"
- */
- std::string normalize(const std::string& filename);
-}
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-#include <config.h>
-
-#include "flip_level_transformer.hpp"
-#include "object/tilemap.hpp"
-#include "object/camera.hpp"
-#include "object/player.hpp"
-#include "badguy/badguy.hpp"
-#include "sector.hpp"
-#include "tile_manager.hpp"
-#include "spawn_point.hpp"
-#include "object/platform.hpp"
-#include "object/block.hpp"
-
-void
-FlipLevelTransformer::transform_sector(Sector* sector)
-{
- float height = sector->get_height();
-
- for(Sector::GameObjects::iterator i = sector->gameobjects.begin();
- i != sector->gameobjects.end(); ++i) {
- GameObject* object = *i;
-
- TileMap* tilemap = dynamic_cast<TileMap*> (object);
- if(tilemap) {
- transform_tilemap(tilemap);
- }
- Player* player = dynamic_cast<Player*> (object);
- if(player) {
- Vector pos = player->get_pos();
- pos.y = height - pos.y - player->get_bbox().get_height();
- player->move(pos);
- continue;
- }
- BadGuy* badguy = dynamic_cast<BadGuy*> (object);
- if(badguy) {
- transform_badguy(height, badguy);
- }
- Platform* platform = dynamic_cast<Platform*> (object);
- if(platform) {
- transform_platform(height, *platform);
- }
- Block* block = dynamic_cast<Block*> (object);
- if(block) {
- transform_block(height, *block);
- }
- MovingObject* mobject = dynamic_cast<MovingObject*> (object);
- if(mobject) {
- transform_moving_object(height, mobject);
- }
- }
- for(Sector::SpawnPoints::iterator i = sector->spawnpoints.begin();
- i != sector->spawnpoints.end(); ++i) {
- transform_spawnpoint(height, *i);
- }
-
- if(sector->camera != 0 && sector->player != 0)
- sector->camera->reset(sector->player->get_pos());
-}
-
-void
-FlipLevelTransformer::transform_tilemap(TileMap* tilemap)
-{
- for(size_t x = 0; x < tilemap->get_width(); ++x) {
- for(size_t y = 0; y < tilemap->get_height()/2; ++y) {
- // swap tiles
- int y2 = tilemap->get_height()-1-y;
- uint32_t t1 = tilemap->get_tile_id(x, y);
- uint32_t t2 = tilemap->get_tile_id(x, y2);
- tilemap->change(x, y, t2);
- tilemap->change(x, y2, t1);
- }
- }
- if(tilemap->get_drawing_effect() != 0) {
- tilemap->set_drawing_effect(NO_EFFECT);
- } else {
- tilemap->set_drawing_effect(VERTICAL_FLIP);
- }
-}
-
-void
-FlipLevelTransformer::transform_badguy(float height, BadGuy* badguy)
-{
- Vector pos = badguy->get_start_position();
- pos.y = height - pos.y;
- badguy->set_start_position(pos);
-}
-
-void
-FlipLevelTransformer::transform_spawnpoint(float height, SpawnPoint* spawn)
-{
- Vector pos = spawn->pos;
- pos.y = height - pos.y;
- spawn->pos = pos;
-}
-
-void
-FlipLevelTransformer::transform_moving_object(float height, MovingObject*object)
-{
- Vector pos = object->get_pos();
- pos.y = height - pos.y - object->get_bbox().get_height();
- object->set_pos(pos);
-}
-
-void
-FlipLevelTransformer::transform_platform(float height, Platform& platform)
-{
- Path& path = platform.get_path();
- for (std::vector<Path::Node>::iterator i = path.nodes.begin(); i != path.nodes.end(); i++) {
- Vector& pos = i->position;
- pos.y = height - pos.y - platform.get_bbox().get_height();
- }
-}
-
-void
-FlipLevelTransformer::transform_block(float height, Block& block)
-{
- if (block.original_y != -1) block.original_y = height - block.original_y - block.get_bbox().get_height();
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-#ifndef __FLIP_LEVEL_TRANSFORMER_H__
-#define __FLIP_LEVEL_TRANSFORMER_H__
-
-#include "level_transformer.hpp"
-
-class TileMap;
-class BadGuy;
-class SpawnPoint;
-class MovingObject;
-class Platform;
-class Block;
-
-/** Vertically or horizontally flip a level */
-class FlipLevelTransformer : public LevelTransformer
-{
-public:
- virtual void transform_sector(Sector* sector);
-
-private:
- void transform_tilemap(TileMap* tilemap);
- void transform_moving_object(float height, MovingObject* object);
- void transform_badguy(float height, BadGuy* badguy);
- void transform_spawnpoint(float height, SpawnPoint* spawnpoint);
- void transform_platform(float height, Platform& platform);
- void transform_block(float height, Block& block);
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
-#include "log.hpp"
-#include "game_object.hpp"
-#include "object_remove_listener.hpp"
-
-GameObject::GameObject()
- : wants_to_die(false), remove_listeners(NULL)
-{
-}
-
-GameObject::~GameObject()
-{
- // call remove listeners (and remove them from the list)
- RemoveListenerListEntry* entry = remove_listeners;
- while(entry != NULL) {
- RemoveListenerListEntry* next = entry->next;
- entry->listener->object_removed(this);
- delete entry;
- entry = next;
- }
-}
-
-
-void
-GameObject::add_remove_listener(ObjectRemoveListener* listener)
-{
- RemoveListenerListEntry* entry = new RemoveListenerListEntry();
- entry->next = remove_listeners;
- entry->listener = listener;
- remove_listeners = entry;
-}
-
-void
-GameObject::del_remove_listener(ObjectRemoveListener* listener)
-{
- RemoveListenerListEntry* entry = remove_listeners;
- if (entry->listener == listener) {
- remove_listeners = entry->next;
- delete entry;
- return;
- }
- RemoveListenerListEntry* next = entry->next;
- while(next != NULL) {
- if (next->listener == listener) {
- entry->next = next->next;
- delete next;
- break;
- }
- entry = next;
- next = next->next;
- }
-}
-
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#ifndef SUPERTUX_GAMEOBJECT_H
-#define SUPERTUX_GAMEOBJECT_H
-
-#include <string>
-#include "refcounter.hpp"
-
-class DrawingContext;
-class ObjectRemoveListener;
-
-/**
- * Base class for all the things that make up Levels' Sectors.
- *
- * Each sector of a level will hold a list of active GameObject while the
- * game is played.
- *
- * This class is responsible for:
- * - Updating and Drawing the object. This should happen in the update() and
- * draw() functions. Both are called once per frame.
- * - Providing a safe way to remove the object by calling the remove_me
- * functions.
- */
-class GameObject : public RefCounter
-{
-public:
- GameObject();
- virtual ~GameObject();
-
- /** This function is called once per frame and allows the object to update
- * it's state. The elapsed_time is the time since the last frame in
- * seconds and should be the base for all timed calculations (don't use
- * SDL_GetTicks directly as this will fail in pause mode)
- */
- virtual void update(float elapsed_time) = 0;
-
- /** The GameObject should draw itself onto the provided DrawingContext if this
- * function is called.
- */
- virtual void draw(DrawingContext& context) = 0;
-
- /** returns true if the object is not scheduled to be removed yet */
- bool is_valid() const
- {
- return !wants_to_die;
- }
-
- /** schedules this object to be removed at the end of the frame */
- void remove_me()
- {
- wants_to_die = true;
- }
-
- /** registers a remove listener which will be called if the object
- * gets removed/destroyed
- */
- void add_remove_listener(ObjectRemoveListener* listener);
-
- /**
- * unregisters a remove listener, so it will no longer be called if the object
- * gets removed/destroyed
- */
- void del_remove_listener(ObjectRemoveListener* listener);
-
- const std::string& get_name() const
- {
- return name;
- }
-
-private:
- /** this flag indicates if the object should be removed at the end of the
- * frame
- */
- bool wants_to_die;
-
- struct RemoveListenerListEntry
- {
- RemoveListenerListEntry* next;
- ObjectRemoveListener* listener;
- };
- RemoveListenerListEntry* remove_listeners;
-
-protected:
- /**
- * a name for the gameobject, this is mostly a hint for scripts and for
- * debugging, don't rely on names being set or being unique
- */
- std::string name;
-};
-
-#endif /*SUPERTUX_GAMEOBJECT_H*/
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include <config.h>
-
-#include "game_session.hpp"
-
-#include <fstream>
-#include <sstream>
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <time.h>
-#include <stdexcept>
-#include <float.h>
-
-#include <SDL.h>
-
-#include "file_system.hpp"
-#include "gameconfig.hpp"
-#include "gettext.hpp"
-#include "level.hpp"
-#include "levelintro.hpp"
-#include "log.hpp"
-#include "main.hpp"
-#include "mainloop.hpp"
-#include "player_status.hpp"
-#include "options_menu.hpp"
-#include "random_generator.hpp"
-#include "sector.hpp"
-#include "statistics.hpp"
-#include "timer.hpp"
-#include "audio/sound_manager.hpp"
-#include "control/codecontroller.hpp"
-#include "control/joystickkeyboardcontroller.hpp"
-#include "gui/menu.hpp"
-#include "object/camera.hpp"
-#include "object/endsequence_fireworks.hpp"
-#include "object/endsequence_walkleft.hpp"
-#include "object/endsequence_walkright.hpp"
-#include "object/level_time.hpp"
-#include "object/player.hpp"
-#include "scripting/squirrel_util.hpp"
-#include "worldmap/worldmap.hpp"
-
-enum GameMenuIDs {
- MNID_CONTINUE,
- MNID_ABORTLEVEL
-};
-
-GameSession* GameSession::current_ = NULL;
-
-GameSession::GameSession(const std::string& levelfile_, Statistics* statistics)
- : level(0), currentsector(0),
- end_sequence(0),
- levelfile(levelfile_), best_level_statistics(statistics),
- capture_demo_stream(0), playback_demo_stream(0), demo_controller(0),
- play_time(0), edit_mode(false), levelintro_shown(false)
-{
- current_ = this;
- currentsector = NULL;
-
- game_pause = false;
- speed_before_pause = main_loop->get_speed();
-
- statistics_backdrop.reset(new Surface("images/engine/menu/score-backdrop.png"));
-
- restart_level();
-
- game_menu.reset(new Menu());
- game_menu->add_label(level->name);
- game_menu->add_hl();
- game_menu->add_entry(MNID_CONTINUE, _("Continue"));
- game_menu->add_submenu(_("Options"), get_options_menu());
- game_menu->add_hl();
- game_menu->add_entry(MNID_ABORTLEVEL, _("Abort Level"));
-}
-
-void
-GameSession::restart_level()
-{
-
- if (edit_mode) {
- force_ghost_mode();
- return;
- }
-
- game_pause = false;
- end_sequence = 0;
-
- main_controller->reset();
-
- currentsector = 0;
-
- level.reset(new Level);
- try {
- level->load(levelfile);
- level->stats.total_coins = level->get_total_coins();
- level->stats.total_badguys = level->get_total_badguys();
- level->stats.total_secrets = level->get_total_secrets();
- level->stats.reset();
-
- if(reset_sector != "") {
- currentsector = level->get_sector(reset_sector);
- if(!currentsector) {
- std::stringstream msg;
- msg << "Couldn't find sector '" << reset_sector << "' for resetting tux.";
- throw std::runtime_error(msg.str());
- }
- level->stats.declare_invalid();
- currentsector->activate(reset_pos);
- } else {
- currentsector = level->get_sector("main");
- if(!currentsector)
- throw std::runtime_error("Couldn't find main sector");
- play_time = 0;
- currentsector->activate("main");
- }
- } catch(std::exception& e) {
- log_fatal << "Couldn't start level: " << e.what() << std::endl;
- main_loop->exit_screen();
- }
-
- sound_manager->stop_music();
- currentsector->play_music(LEVEL_MUSIC);
-
- if(capture_file != "") {
- int newSeed=0; // next run uses a new seed
- while (newSeed == 0) // which is the next non-zero random num.
- newSeed = systemRandom.rand();
- config->random_seed = systemRandom.srand(newSeed);
- log_info << "Next run uses random seed " <<config->random_seed <<std::endl;
- record_demo(capture_file);
- }
-}
-
-GameSession::~GameSession()
-{
- delete capture_demo_stream;
- delete playback_demo_stream;
- delete demo_controller;
- free_options_menu();
-
- current_ = NULL;
-}
-
-void
-GameSession::record_demo(const std::string& filename)
-{
- delete capture_demo_stream;
-
- capture_demo_stream = new std::ofstream(filename.c_str());
- if(!capture_demo_stream->good()) {
- std::stringstream msg;
- msg << "Couldn't open demo file '" << filename << "' for writing.";
- throw std::runtime_error(msg.str());
- }
- capture_file = filename;
-
- char buf[30]; // save the seed in the demo file
- snprintf(buf, sizeof(buf), "random_seed=%10d", config->random_seed);
- for (int i=0; i==0 || buf[i-1]; i++)
- capture_demo_stream->put(buf[i]);
-}
-
-int
-GameSession::get_demo_random_seed(const std::string& filename)
-{
- std::istream* test_stream = new std::ifstream(filename.c_str());
- if(test_stream->good()) {
- char buf[30]; // recall the seed from the demo file
- int seed;
- for (int i=0; i<30 && (i==0 || buf[i-1]); i++)
- test_stream->get(buf[i]);
- if (sscanf(buf, "random_seed=%10d", &seed) == 1) {
- log_info << "Random seed " << seed << " from demo file" << std::endl;
- return seed;
- }
- else
- log_info << "Demo file contains no random number" << std::endl;
- }
- return 0;
-}
-
-void
-GameSession::play_demo(const std::string& filename)
-{
- delete playback_demo_stream;
- delete demo_controller;
-
- playback_demo_stream = new std::ifstream(filename.c_str());
- if(!playback_demo_stream->good()) {
- std::stringstream msg;
- msg << "Couldn't open demo file '" << filename << "' for reading.";
- throw std::runtime_error(msg.str());
- }
-
- Player& tux = *currentsector->player;
- demo_controller = new CodeController();
- tux.set_controller(demo_controller);
-
- // skip over random seed, if it exists in the file
- char buf[30]; // ascii decimal seed
- int seed;
- for (int i=0; i<30 && (i==0 || buf[i-1]); i++)
- playback_demo_stream->get(buf[i]);
- if (sscanf(buf, "random_seed=%010d", &seed) != 1)
- playback_demo_stream->seekg(0); // old style w/o seed, restart at beg
-}
-
-void
-GameSession::on_escape_press()
-{
- if(currentsector->player->is_dying() || end_sequence)
- {
- // Let the timers run out, we fast-forward them to force past a sequence
- if (end_sequence)
- end_sequence->stop();
-
- currentsector->player->dying_timer.start(FLT_EPSILON);
- return; // don't let the player open the menu, when he is dying
- }
-
- if(level->on_menukey_script != "") {
- std::istringstream in(level->on_menukey_script);
- run_script(in, "OnMenuKeyScript");
- } else {
- toggle_pause();
- }
-}
-
-void
-GameSession::toggle_pause()
-{
- // pause
- if(!game_pause) {
- speed_before_pause = main_loop->get_speed();
- main_loop->set_speed(0);
- Menu::set_current(game_menu.get());
- game_menu->set_active_item(MNID_CONTINUE);
- game_pause = true;
- }
-
- // unpause is done in update() after the menu is processed
-}
-
-void
-GameSession::set_editmode(bool edit_mode)
-{
- if (this->edit_mode == edit_mode) return;
- this->edit_mode = edit_mode;
-
- currentsector->get_players()[0]->set_edit_mode(edit_mode);
-
- if (edit_mode) {
-
- // entering edit mode
-
- } else {
-
- // leaving edit mode
- restart_level();
-
- }
-}
-
-void
-GameSession::force_ghost_mode()
-{
- currentsector->get_players()[0]->set_ghost_mode(true);
-}
-
-HSQUIRRELVM
-GameSession::run_script(std::istream& in, const std::string& sourcename)
-{
- using namespace Scripting;
-
- // garbage collect thread list
- for(ScriptList::iterator i = scripts.begin();
- i != scripts.end(); ) {
- HSQOBJECT& object = *i;
- HSQUIRRELVM vm = object_to_vm(object);
-
- if(sq_getvmstate(vm) != SQ_VMSTATE_SUSPENDED) {
- sq_release(global_vm, &object);
- i = scripts.erase(i);
- continue;
- }
-
- ++i;
- }
-
- HSQOBJECT object = create_thread(global_vm);
- scripts.push_back(object);
-
- HSQUIRRELVM vm = object_to_vm(object);
-
- compile_and_run(vm, in, sourcename);
-
- return vm;
-}
-
-void
-GameSession::process_events()
-{
- // end of pause mode?
- // XXX this looks like a fail-safe to unpause the game if there's no menu
- // XXX having it enabled causes some unexpected problems
- // XXX hopefully disabling it won't...
- /*
- if(!Menu::current() && game_pause) {
- game_pause = false;
- }
- */
-
- // playback a demo?
- if(playback_demo_stream != 0) {
- demo_controller->update();
- char left = false;
- char right = false;
- char up = false;
- char down = false;
- char jump = false;
- char action = false;
- playback_demo_stream->get(left);
- playback_demo_stream->get(right);
- playback_demo_stream->get(up);
- playback_demo_stream->get(down);
- playback_demo_stream->get(jump);
- playback_demo_stream->get(action);
- demo_controller->press(Controller::LEFT, left);
- demo_controller->press(Controller::RIGHT, right);
- demo_controller->press(Controller::UP, up);
- demo_controller->press(Controller::DOWN, down);
- demo_controller->press(Controller::JUMP, jump);
- demo_controller->press(Controller::ACTION, action);
- }
-
- // save input for demo?
- if(capture_demo_stream != 0) {
- capture_demo_stream ->put(main_controller->hold(Controller::LEFT));
- capture_demo_stream ->put(main_controller->hold(Controller::RIGHT));
- capture_demo_stream ->put(main_controller->hold(Controller::UP));
- capture_demo_stream ->put(main_controller->hold(Controller::DOWN));
- capture_demo_stream ->put(main_controller->hold(Controller::JUMP));
- capture_demo_stream ->put(main_controller->hold(Controller::ACTION));
- }
-}
-
-void
-GameSession::check_end_conditions()
-{
- Player* tux = currentsector->player;
-
- /* End of level? */
- if(end_sequence && end_sequence->is_done()) {
- finish(true);
- } else if (!end_sequence && tux->is_dead()) {
- restart_level();
- }
-}
-
-void
-GameSession::draw(DrawingContext& context)
-{
- currentsector->draw(context);
- drawstatus(context);
-
- if(game_pause)
- draw_pause(context);
-}
-
-void
-GameSession::draw_pause(DrawingContext& context)
-{
- context.draw_filled_rect(
- Vector(0,0), Vector(SCREEN_WIDTH, SCREEN_HEIGHT),
- Color(0.0f, 0.0f, 0.0f, .25f), LAYER_FOREGROUND1);
-}
-
-void
-GameSession::process_menu()
-{
- Menu* menu = Menu::current();
- if(menu) {
- if(menu == game_menu.get()) {
- switch (game_menu->check()) {
- case MNID_CONTINUE:
- Menu::set_current(0);
- toggle_pause();
- break;
- case MNID_ABORTLEVEL:
- Menu::set_current(0);
- main_loop->exit_screen();
- break;
- }
- }
- }
-}
-
-void
-GameSession::setup()
-{
- current_ = this;
-
- if(currentsector != Sector::current()) {
- currentsector->activate(currentsector->player->get_pos());
- }
- currentsector->play_music(LEVEL_MUSIC);
-
- // Eat unneeded events
- SDL_Event event;
- while(SDL_PollEvent(&event))
- {}
-
- if (!levelintro_shown) {
- levelintro_shown = true;
- main_loop->push_screen(new LevelIntro(level.get(), best_level_statistics));
- }
-}
-
-void
-GameSession::update(float elapsed_time)
-{
- // handle controller
- if(main_controller->pressed(Controller::PAUSE_MENU))
- on_escape_press();
-
- process_events();
- process_menu();
-
- // Unpause the game if the menu has been closed
- if (game_pause && !Menu::current()) {
- main_loop->set_speed(speed_before_pause);
- game_pause = false;
- }
-
- check_end_conditions();
-
- // respawning in new sector?
- if(newsector != "" && newspawnpoint != "") {
- Sector* sector = level->get_sector(newsector);
- if(sector == 0) {
- log_warning << "Sector '" << newsector << "' not found" << std::endl;
- sector = level->get_sector("main");
- }
- sector->activate(newspawnpoint);
- sector->play_music(LEVEL_MUSIC);
- currentsector = sector;
- //Keep persistent across sectors
- if(edit_mode)
- currentsector->get_players()[0]->set_edit_mode(edit_mode);
- newsector = "";
- newspawnpoint = "";
- }
-
- // Update the world state and all objects in the world
- if(!game_pause) {
- // Update the world
- if (!end_sequence) {
- play_time += elapsed_time; //TODO: make sure we don't count cutscene time
- level->stats.time = play_time;
- currentsector->update(elapsed_time);
- } else {
- if (!end_sequence->is_tux_stopped()) {
- currentsector->update(elapsed_time);
- } else {
- end_sequence->update(elapsed_time);
- }
- }
- }
-
- // update sounds
- if (currentsector && currentsector->camera) sound_manager->set_listener_position(currentsector->camera->get_center());
-
- /* Handle music: */
- if (end_sequence)
- return;
-
- if(currentsector->player->invincible_timer.started()) {
- if(currentsector->player->invincible_timer.get_timeleft() <=
- TUX_INVINCIBLE_TIME_WARNING) {
- currentsector->play_music(HERRING_WARNING_MUSIC);
- } else {
- currentsector->play_music(HERRING_MUSIC);
- }
- } else if(currentsector->get_music_type() != LEVEL_MUSIC) {
- currentsector->play_music(LEVEL_MUSIC);
- }
-}
-
-void
-GameSession::finish(bool win)
-{
- using namespace WorldMapNS;
-
- if (edit_mode) {
- force_ghost_mode();
- return;
- }
-
- if(win) {
- if(WorldMap::current())
- WorldMap::current()->finished_level(level.get());
- }
-
- main_loop->exit_screen();
-}
-
-void
-GameSession::respawn(const std::string& sector, const std::string& spawnpoint)
-{
- newsector = sector;
- newspawnpoint = spawnpoint;
-}
-
-void
-GameSession::set_reset_point(const std::string& sector, const Vector& pos)
-{
- reset_sector = sector;
- reset_pos = pos;
-}
-
-std::string
-GameSession::get_working_directory()
-{
- return FileSystem::dirname(levelfile);
-}
-
-void
-GameSession::start_sequence(const std::string& sequencename)
-{
- // do not play sequences when in edit mode
- if (edit_mode) {
- force_ghost_mode();
- return;
- }
-
- // handle special "stoptux" sequence
- if (sequencename == "stoptux") {
- if (!end_sequence) {
- log_warning << "Final target reached without an active end sequence" << std::endl;
- this->start_sequence("endsequence");
- }
- if (end_sequence) end_sequence->stop_tux();
- return;
- }
-
- // abort if a sequence is already playing
- if (end_sequence)
- return;
-
- if (sequencename == "endsequence") {
- if (currentsector->get_players()[0]->physic.get_velocity_x() < 0) {
- end_sequence = new EndSequenceWalkLeft();
- } else {
- end_sequence = new EndSequenceWalkRight();
- }
- } else if (sequencename == "fireworks") {
- end_sequence = new EndSequenceFireworks();
- } else {
- log_warning << "Unknown sequence '" << sequencename << "'. Ignoring." << std::endl;
- return;
- }
-
- /* slow down the game for end-sequence */
- main_loop->set_speed(0.5f);
-
- currentsector->add_object(end_sequence);
- end_sequence->start();
-
- sound_manager->play_music("music/leveldone.music", false);
- currentsector->player->invincible_timer.start(10000.0f);
-
- // Stop all clocks.
- for(std::vector<GameObject*>::iterator i = currentsector->gameobjects.begin();
- i != currentsector->gameobjects.end(); ++i)
- {
- GameObject* obj = *i;
-
- LevelTime* lt = dynamic_cast<LevelTime*> (obj);
- if(lt)
- lt->stop();
- }
-}
-
-/* (Status): */
-void
-GameSession::drawstatus(DrawingContext& context)
-{
- player_status->draw(context);
-
- // draw level stats while end_sequence is running
- if (end_sequence) {
- level->stats.draw_endseq_panel(context, best_level_statistics, statistics_backdrop.get());
- }
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#ifndef SUPERTUX_GAMELOOP_H
-#define SUPERTUX_GAMELOOP_H
-
-#include <string>
-#include <SDL.h>
-#include <squirrel.h>
-#include "screen.hpp"
-#include "math/vector.hpp"
-#include "video/surface.hpp"
-#include "object/endsequence.hpp"
-
-class Level;
-class Sector;
-class Statistics;
-class DrawingContext;
-class CodeController;
-class Menu;
-
-/**
- * Screen that runs a Level, where Players run and jump through Sectors.
- */
-class GameSession : public Screen
-{
-public:
- GameSession(const std::string& levelfile, Statistics* statistics = NULL);
- ~GameSession();
-
- void record_demo(const std::string& filename);
- int get_demo_random_seed(const std::string& filename);
- void play_demo(const std::string& filename);
-
- void draw(DrawingContext& context);
- void update(float frame_ratio);
- void setup();
-
- void set_current()
- { current_ = this; }
- static GameSession* current()
- { return current_; }
-
- /// ends the current level
- void finish(bool win = true);
- void respawn(const std::string& sectorname, const std::string& spawnpointname);
- void set_reset_point(const std::string& sectorname, const Vector& pos);
- std::string get_reset_point_sectorname()
- { return reset_sector; }
-
- Vector get_reset_point_pos()
- { return reset_pos; }
-
- Sector* get_current_sector()
- { return currentsector; }
-
- Level* get_current_level()
- { return level.get(); }
-
- void start_sequence(const std::string& sequencename);
-
- /**
- * returns the "working directory" usually this is the directory where the
- * currently played level resides. This is used when locating additional
- * resources for the current level/world
- */
- std::string get_working_directory();
- void restart_level();
-
- void toggle_pause();
-
- /**
- * Enters or leaves level editor mode
- */
- void set_editmode(bool edit_mode = true);
-
- /**
- * Forces all Players to enter ghost mode
- */
- void force_ghost_mode();
-
-private:
- void check_end_conditions();
- void process_events();
- void capture_demo_step();
-
- void drawstatus(DrawingContext& context);
- void draw_pause(DrawingContext& context);
-
- HSQUIRRELVM run_script(std::istream& in, const std::string& sourcename);
- void on_escape_press();
- void process_menu();
-
- std::auto_ptr<Level> level;
- std::auto_ptr<Surface> statistics_backdrop;
-
- // scripts
- typedef std::vector<HSQOBJECT> ScriptList;
- ScriptList scripts;
-
- Sector* currentsector;
-
- int levelnb;
- int pause_menu_frame;
-
- EndSequence* end_sequence;
-
- bool game_pause;
- float speed_before_pause;
-
- std::string levelfile;
-
- // reset point (the point where tux respawns if he dies)
- std::string reset_sector;
- Vector reset_pos;
-
- // the sector and spawnpoint we should spawn after this frame
- std::string newsector;
- std::string newspawnpoint;
-
- static GameSession* current_;
-
- Statistics* best_level_statistics;
-
- std::ostream* capture_demo_stream;
- std::string capture_file;
- std::istream* playback_demo_stream;
- CodeController* demo_controller;
-
- std::auto_ptr<Menu> game_menu;
-
- float play_time; /**< total time in seconds that this session ran interactively */
-
- bool edit_mode; /**< true if GameSession runs in level editor mode */
- bool levelintro_shown; /**< true if the LevelIntro screen was already shown */
-};
-
-#endif /*SUPERTUX_GAMELOOP_H*/
+++ /dev/null
-// $Id$
-//
-// SuperTux - A Jump'n Run
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include <config.h>
-
-#include "gameconfig.hpp"
-
-#include <stdlib.h>
-#include <string>
-#include <stdexcept>
-
-#include "lisp/parser.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-#include "control/joystickkeyboardcontroller.hpp"
-#include "resources.hpp"
-#include "main.hpp"
-#include "addon/addon_manager.hpp"
-
-Config* config = 0;
-
-Config::Config()
-{
- profile = 1;
- use_fullscreen = false;
- video = AUTO_VIDEO;
- try_vsync = true;
- show_fps = false;
- sound_enabled = true;
- music_enabled = true;
- console_enabled = false;
- random_seed = 0; // set by time(), by default (unless in config)
-
- window_width = 800;
- window_height = 600;
-
- fullscreen_width = 800;
- fullscreen_height = 600;
-
- magnification = 1.0f;
-
- aspect_width = 0; // auto detect
- aspect_height = 0;
-
- enable_script_debugger = false;
-
- locale = ""; // autodetect
-}
-
-Config::~Config()
-{}
-
-void
-Config::load()
-{
- lisp::Parser parser;
- const lisp::Lisp* root = parser.parse("config");
-
- const lisp::Lisp* config_lisp = root->get_lisp("supertux-config");
- if(!config_lisp)
- throw std::runtime_error("File is not a supertux-config file");
-
- config_lisp->get("show_fps", show_fps);
- config_lisp->get("console", console_enabled);
- config_lisp->get("locale", locale);
- config_lisp->get("random_seed", random_seed);
-
- const lisp::Lisp* config_video_lisp = config_lisp->get_lisp("video");
- if(config_video_lisp) {
- config_video_lisp->get("fullscreen", use_fullscreen);
- std::string video_string;
- config_video_lisp->get("video", video_string);
- video = get_video_system(video_string);
- config_video_lisp->get("vsync", try_vsync);
-
- config_video_lisp->get("fullscreen_width", fullscreen_width);
- config_video_lisp->get("fullscreen_height", fullscreen_height);
-
- config_video_lisp->get("window_width", window_width);
- config_video_lisp->get("window_height", window_height);
-
- config_video_lisp->get("aspect_width", aspect_width);
- config_video_lisp->get("aspect_height", aspect_height);
- }
-
- const lisp::Lisp* config_audio_lisp = config_lisp->get_lisp("audio");
- if(config_audio_lisp) {
- config_audio_lisp->get("sound_enabled", sound_enabled);
- config_audio_lisp->get("music_enabled", music_enabled);
- }
-
- const lisp::Lisp* config_control_lisp = config_lisp->get_lisp("control");
- if(config_control_lisp && main_controller) {
- main_controller->read(*config_control_lisp);
- }
-
- const lisp::Lisp* config_addons_lisp = config_lisp->get_lisp("addons");
- if(config_addons_lisp) {
- AddonManager::get_instance().read(*config_addons_lisp);
- }
-}
-
-void
-Config::save()
-{
- lisp::Writer writer("config");
-
- writer.start_list("supertux-config");
-
- writer.write("show_fps", show_fps);
- writer.write("console", console_enabled);
- writer.write("locale", locale);
-
- writer.start_list("video");
- writer.write("fullscreen", use_fullscreen);
- writer.write("video", get_video_string(video));
- writer.write("vsync", try_vsync);
-
- writer.write("fullscreen_width", fullscreen_width);
- writer.write("fullscreen_height", fullscreen_height);
-
- writer.write("window_width", window_width);
- writer.write("window_height", window_height);
-
- writer.write("aspect_width", aspect_width);
- writer.write("aspect_height", aspect_height);
-
- writer.end_list("video");
-
- writer.start_list("audio");
- writer.write("sound_enabled", sound_enabled);
- writer.write("music_enabled", music_enabled);
- writer.end_list("audio");
-
- if(main_controller) {
- writer.start_list("control");
- main_controller->write(writer);
- writer.end_list("control");
- }
-
- writer.start_list("addons");
- AddonManager::get_instance().write(writer);
- writer.end_list("addons");
-
- writer.end_list("supertux-config");
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux=
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#ifndef SUPERTUX_CONFIG_H
-#define SUPERTUX_CONFIG_H
-
-#include <config.h>
-
-#include <string>
-
-#include "video/video_systems.hpp"
-
-class Config
-{
-public:
- Config();
- ~Config();
-
- void load();
- void save();
-
- int profile;
-
- // the width/height to be used to display the game in fullscreen
- int fullscreen_width;
- int fullscreen_height;
-
- // the width/height of the window managers window
- int window_width;
- int window_height;
-
- // the aspect ratio
- int aspect_width;
- int aspect_height;
-
- float magnification;
-
- bool use_fullscreen;
- VideoSystem video;
- bool try_vsync;
- bool show_fps;
- bool sound_enabled;
- bool music_enabled;
- bool console_enabled;
-
- int random_seed; // initial random seed. 0 ==> set from time()
-
- /** this variable is set if supertux should start in a specific level */
- std::string start_level;
- bool enable_script_debugger;
- std::string start_demo;
- std::string record_demo;
-
- std::string locale; /**< force SuperTux language to this locale, e.g. "de". A file "data/locale/xx.po" must exist for this to work. An empty string means autodetect. */
-};
-
-extern Config* config;
-
-#endif
+++ /dev/null
-/*
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU Library General Public License as published
- by the Free Software Foundation; either version 2, 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
- USA. */
-#ifndef _LIBGETTEXT_H
-#define _LIBGETTEXT_H
-
-#include "tinygettext/tinygettext.hpp"
-
-extern TinyGetText::DictionaryManager dictionary_manager;
-
-static inline const char* _(const char* message)
-{
- return dictionary_manager.get_dictionary().translate(message);
-}
-
-static inline std::string _(const std::string& message)
-{
- return dictionary_manager.get_dictionary().translate(message);
-}
-
-static inline const char* N_(const char* id, const char* id2, int num)
-{
- return dictionary_manager.get_dictionary().translate(id, id2, num).c_str();
-}
-
-#endif /* _LIBGETTEXT_H */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "button.hpp"
+#include "gui/button.hpp"
-#include <SDL.h>
-#include <iostream>
-
-#include "main.hpp"
-#include "mousecursor.hpp"
-#include "video/font.hpp"
-#include "video/surface.hpp"
+#include "supertux/main.hpp"
#include "video/drawing_context.hpp"
Font* Button::info_font = 0;
-extern SDL_Surface* screen;
-
-/* Buttons */
-Button::Button(Surface* image_, std::string info_, SDLKey binding_)
- : binding(binding_)
+Button::Button(Surface* image_, std::string info_, SDLKey binding_) :
+ pos(),
+ size(),
+ image(),
+ binding(binding_),
+ id(),
+ state(),
+ info()
{
image = image_;
size = Vector(image->get_width(), image->get_height());
void Button::draw(DrawingContext &context, bool selected)
{
-if(selected)
- context.draw_filled_rect(pos, size, Color (200,240,220), LAYER_GUI);
-else
- context.draw_filled_rect(pos, size, Color (200,200,220), LAYER_GUI);
-
-Vector tanslation = -context.get_translation();
-if(state == BT_SHOW_INFO)
- {
- Vector offset;
- if(pos.x + tanslation.x < 100 && pos.y + tanslation.y > SCREEN_HEIGHT - 20)
- offset = Vector(size.x, - 10);
- else if(pos.x + tanslation.x < 100)
- offset = Vector(size.x, 0);
+ if(selected)
+ context.draw_filled_rect(pos, size, Color (200,240,220), LAYER_GUI);
else
- offset = Vector(-30, -size.y/2);
- context.draw_text(info_font, info, pos + offset, ALIGN_LEFT, LAYER_GUI+2);
- if(binding != 0)
- context.draw_text(info_font, "(" + std::string(SDL_GetKeyName(binding)) +
- ")", pos + offset + Vector(0,12),
- ALIGN_LEFT, LAYER_GUI+2);
- }
-
-context.draw_surface_part(image, Vector(0,0), size, pos, LAYER_GUI+1);
-}
+ context.draw_filled_rect(pos, size, Color (200,200,220), LAYER_GUI);
-int Button::event(SDL_Event &event, int x_offset, int y_offset)
-{
-state = BT_NONE;
-switch(event.type)
+ Vector tanslation = -context.get_translation();
+ if(state == BT_SHOW_INFO)
{
- case SDL_MOUSEBUTTONDOWN:
- if(event.button.x > pos.x + x_offset && event.button.x < pos.x + x_offset + size.x &&
- event.button.y > pos.y + y_offset && event.button.y < pos.y + y_offset + size.y)
- {
- if(event.button.button == SDL_BUTTON_RIGHT)
- state = BT_SHOW_INFO;
- }
- break;
- case SDL_MOUSEBUTTONUP:
- if(event.button.x > pos.x + x_offset && event.button.x < pos.x + x_offset + size.x &&
- event.button.y > pos.y + y_offset && event.button.y < pos.y + y_offset + size.y)
- {
- if(event.button.button == SDL_BUTTON_LEFT)
- state = BT_SELECTED;
- }
- break;
- case SDL_KEYDOWN: // key pressed
- if(event.key.keysym.sym == binding)
- state = BT_SELECTED;
- break;
- default:
- break;
+ Vector offset;
+ if(pos.x + tanslation.x < 100 && pos.y + tanslation.y > SCREEN_HEIGHT - 20)
+ offset = Vector(size.x, - 10);
+ else if(pos.x + tanslation.x < 100)
+ offset = Vector(size.x, 0);
+ else
+ offset = Vector(-30, -size.y/2);
+ context.draw_text(info_font, info, pos + offset, ALIGN_LEFT, LAYER_GUI+2);
+ if(binding != 0)
+ context.draw_text(info_font, "(" + std::string(SDL_GetKeyName(binding)) +
+ ")", pos + offset + Vector(0,12),
+ ALIGN_LEFT, LAYER_GUI+2);
}
-return state;
-}
-
-/* Group of buttons */
-
-ButtonGroup::ButtonGroup(Vector pos_, Vector buttons_size_, Vector buttons_box_)
- : pos(pos_), buttons_size(buttons_size_), buttons_box(buttons_box_)
-{
-buttons.clear();
-row = 0;
-button_selected = -1;
-mouse_hover = false;
-mouse_left_button = false;
-buttons_pair_nb = 0;
-}
-
-ButtonGroup::~ButtonGroup()
-{
-}
-
-void ButtonGroup::add_button(Button button, int id, bool select)
-{
-button.pos.x = ((buttons.size()-buttons_pair_nb) % (int)buttons_box.x) * buttons_size.x;
-button.pos.y = ((int)((buttons.size()-buttons_pair_nb) / buttons_box.x)) * buttons_size.y;
-button.size = buttons_size;
-button.id = id;
-if(select)
- button_selected = id;
-
-buttons.push_back(button);
-}
-
-void ButtonGroup::add_pair_of_buttons(Button button1, int id1, Button button2, int id2)
-{
-button1.pos.x = button2.pos.x = ((buttons.size()-buttons_pair_nb) % (int)buttons_box.x) * buttons_size.x;
-button1.pos.y = button2.pos.y = ((int)((buttons.size()-buttons_pair_nb) / buttons_box.x)) * buttons_size.y;
-button1.size.x = button2.size.x = buttons_size.x;
-button1.size.y = button2.size.y = buttons_size.y / 2;
-button2.pos.y += buttons_size.y / 2;
-button1.id = id1;
-button2.id = id2;
-
-buttons_pair_nb++;
-buttons.push_back(button1);
-buttons.push_back(button2);
-}
-
-void ButtonGroup::draw(DrawingContext &context)
-{
-context.draw_filled_rect(pos - Vector(12,4),
- Vector(buttons_size.x*buttons_box.x + 16, buttons_size.y*buttons_box.y + 8),
- Color (0,0,0, 128), LAYER_GUI-1);
-
-context.push_transform();
-context.set_translation(Vector(-pos.x, -pos.y + buttons_size.y*row));
-for(Buttons::iterator i = buttons.begin(); i != buttons.end(); ++i)
- {
- if(i->pos.y < row*buttons_size.y ||
- i->pos.y + i->size.y > (row + buttons_box.y) * buttons_size.y)
- continue;
- i->draw(context, i->id == button_selected);
- }
-context.pop_transform();
+ context.draw_surface_part(image, Vector(0,0), size, pos, LAYER_GUI+1);
}
-bool ButtonGroup::event(SDL_Event &event)
+int Button::event(SDL_Event &event, int x_offset, int y_offset)
{
-bool caught_event = false;
-
-switch(event.type)
+ state = BT_NONE;
+ switch(event.type)
{
- case SDL_MOUSEMOTION:
- mouse_hover = false;
-
- if(mouse_left_button)
+ case SDL_MOUSEBUTTONDOWN:
+ if(event.button.x > pos.x + x_offset && event.button.x < pos.x + x_offset + size.x &&
+ event.button.y > pos.y + y_offset && event.button.y < pos.y + y_offset + size.y)
{
- pos.x += int(event.motion.xrel * float(SCREEN_WIDTH)/screen->w);
- pos.y += int(event.motion.yrel * float(SCREEN_HEIGHT)/screen->h);
- caught_event = true;
+ if(event.button.button == SDL_BUTTON_RIGHT)
+ state = BT_SHOW_INFO;
}
- if(event.button.x > pos.x-12 && event.button.x < pos.x+16 + buttons_box.x*buttons_size.x &&
- event.button.y > pos.y-4 && event.button.y < pos.y+8 + buttons_box.y*buttons_size.y)
- mouse_hover = true;
- break;
- case SDL_MOUSEBUTTONDOWN:
- if(event.button.x < pos.x-12 || event.button.x > pos.x+16 +
- buttons_box.x*buttons_size.x || event.button.y < pos.y-4 ||
- event.button.y > pos.y+8 + buttons_box.y*buttons_size.y)
break;
-
- caught_event = true;
-
- if(event.button.button == SDL_BUTTON_WHEELUP)
- {
- row--;
- if(row < 0)
- row = 0;
- }
- else if(event.button.button == SDL_BUTTON_WHEELDOWN)
+ case SDL_MOUSEBUTTONUP:
+ if(event.button.x > pos.x + x_offset && event.button.x < pos.x + x_offset + size.x &&
+ event.button.y > pos.y + y_offset && event.button.y < pos.y + y_offset + size.y)
{
- row++;
- if(row > (int)((buttons.size()-buttons_pair_nb)/buttons_box.x) - (int)buttons_box.y +
- ((int)(buttons.size()-buttons_pair_nb)%(int)buttons_box.x != 0 ? 1 : 0))
- row = (int)((buttons.size()-buttons_pair_nb)/buttons_box.x) - (int)buttons_box.y +
- ((int)(buttons.size()-buttons_pair_nb)%(int)buttons_box.x != 0 ? 1 : 0);
+ if(event.button.button == SDL_BUTTON_LEFT)
+ state = BT_SELECTED;
}
- else if(event.button.button == SDL_BUTTON_LEFT)
- mouse_left_button = true;
- else
- caught_event = false;
- break;
- case SDL_MOUSEBUTTONUP:
- mouse_left_button = false;
- break;
- default:
- break;
- }
-
-if(caught_event)
- return true;
-
-for(Buttons::iterator i = buttons.begin(); i != buttons.end(); ++i)
- {
- if(i->pos.y < row*buttons_size.y ||
- i->pos.y + i->size.y > (row + buttons_box.y) * buttons_size.y)
- continue;
-
- if(i->event(event, (int)pos.x,
- (int)pos.y - row*(int)buttons_size.y) == BT_SELECTED)
- {
- button_selected = i->id;
- caught_event = true;
- break;
- }
+ break;
+ case SDL_KEYDOWN: // key pressed
+ if(event.key.keysym.sym == binding)
+ state = BT_SELECTED;
+ break;
+ default:
+ break;
}
-
-return caught_event;
+ return state;
}
-int ButtonGroup::selected_id()
-{
-return button_selected;
-}
-
-void ButtonGroup::set_unselected()
-{
-button_selected = -1;
-}
-
-bool ButtonGroup::is_hover()
-{
-return mouse_hover;
-}
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef SUPERTUX_BUTTON_H
-#define SUPERTUX_BUTTON_H
+#ifndef HEADER_SUPERTUX_GUI_BUTTON_HPP
+#define HEADER_SUPERTUX_GUI_BUTTON_HPP
-#include <vector>
+#include <SDL.h>
#include <string>
-
-#include "SDL.h"
+#include <vector>
#include "math/vector.hpp"
BT_HOVER,
BT_SELECTED,
BT_SHOW_INFO
- };
+};
class Button
{
private:
friend class ButtonGroup;
- Vector pos, size;
+ Vector pos;
+ Vector size;
Surface* image;
SDLKey binding;
std::string info;
};
-class ButtonGroup
-{
-public:
- ButtonGroup(Vector pos_, Vector size_, Vector button_box_);
- ~ButtonGroup();
-
- void draw(DrawingContext& context);
- bool event(SDL_Event& event);
-
- void add_button(Button button, int id, bool select = false);
- void add_pair_of_buttons(Button button1, int id1, Button button2, int id2);
-
- int selected_id();
- void set_unselected();
- bool is_hover();
-
-private:
- Vector pos, buttons_size, buttons_box;
- typedef std::vector <Button> Buttons;
- Buttons buttons;
-
- int button_selected, row;
- bool mouse_hover, mouse_left_button;
-
- int buttons_pair_nb;
-};
-
#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include "gui/button_group.hpp"
+
+#include "supertux/main.hpp"
+#include "video/drawing_context.hpp"
+
+extern SDL_Surface* g_screen;
+
+ButtonGroup::ButtonGroup(Vector pos_, Vector buttons_size_, Vector buttons_box_) :
+ pos(pos_),
+ buttons_size(buttons_size_),
+ buttons_box(buttons_box_)
+{
+ buttons.clear();
+ row = 0;
+ button_selected = -1;
+ mouse_hover = false;
+ mouse_left_button = false;
+ buttons_pair_nb = 0;
+}
+
+ButtonGroup::~ButtonGroup()
+{
+}
+
+void
+ButtonGroup::add_button(Button button, int id, bool select)
+{
+ button.pos.x = ((buttons.size()-buttons_pair_nb) % (int)buttons_box.x) * buttons_size.x;
+ button.pos.y = ((int)((buttons.size()-buttons_pair_nb) / buttons_box.x)) * buttons_size.y;
+ button.size = buttons_size;
+ button.id = id;
+ if(select)
+ button_selected = id;
+
+ buttons.push_back(button);
+}
+
+void
+ButtonGroup::add_pair_of_buttons(Button button1, int id1, Button button2, int id2)
+{
+ button1.pos.x = button2.pos.x = ((buttons.size()-buttons_pair_nb) % (int)buttons_box.x) * buttons_size.x;
+ button1.pos.y = button2.pos.y = ((int)((buttons.size()-buttons_pair_nb) / buttons_box.x)) * buttons_size.y;
+ button1.size.x = button2.size.x = buttons_size.x;
+ button1.size.y = button2.size.y = buttons_size.y / 2;
+ button2.pos.y += buttons_size.y / 2;
+ button1.id = id1;
+ button2.id = id2;
+
+ buttons_pair_nb++;
+ buttons.push_back(button1);
+ buttons.push_back(button2);
+}
+
+void
+ButtonGroup::draw(DrawingContext &context)
+{
+ context.draw_filled_rect(pos - Vector(12,4),
+ Vector(buttons_size.x*buttons_box.x + 16, buttons_size.y*buttons_box.y + 8),
+ Color (0,0,0, 128), LAYER_GUI-1);
+
+ context.push_transform();
+ context.set_translation(Vector(-pos.x, -pos.y + buttons_size.y*row));
+ for(Buttons::iterator i = buttons.begin(); i != buttons.end(); ++i)
+ {
+ if(i->pos.y < row*buttons_size.y ||
+ i->pos.y + i->size.y > (row + buttons_box.y) * buttons_size.y)
+ continue;
+
+ i->draw(context, i->id == button_selected);
+ }
+ context.pop_transform();
+}
+
+bool
+ButtonGroup::event(SDL_Event &event)
+{
+ bool caught_event = false;
+
+ switch(event.type)
+ {
+ case SDL_MOUSEMOTION:
+ mouse_hover = false;
+
+ if(mouse_left_button)
+ {
+ pos.x += int(event.motion.xrel * float(SCREEN_WIDTH)/g_screen->w);
+ pos.y += int(event.motion.yrel * float(SCREEN_HEIGHT)/g_screen->h);
+ caught_event = true;
+ }
+ if(event.button.x > pos.x-12 && event.button.x < pos.x+16 + buttons_box.x*buttons_size.x &&
+ event.button.y > pos.y-4 && event.button.y < pos.y+8 + buttons_box.y*buttons_size.y)
+ mouse_hover = true;
+ break;
+ case SDL_MOUSEBUTTONDOWN:
+ if(event.button.x < pos.x-12 || event.button.x > pos.x+16 +
+ buttons_box.x*buttons_size.x || event.button.y < pos.y-4 ||
+ event.button.y > pos.y+8 + buttons_box.y*buttons_size.y)
+ break;
+
+ caught_event = true;
+
+ if(event.button.button == SDL_BUTTON_WHEELUP)
+ {
+ row--;
+ if(row < 0)
+ row = 0;
+ }
+ else if(event.button.button == SDL_BUTTON_WHEELDOWN)
+ {
+ row++;
+ if(row > (int)((buttons.size()-buttons_pair_nb)/buttons_box.x) - (int)buttons_box.y +
+ ((int)(buttons.size()-buttons_pair_nb)%(int)buttons_box.x != 0 ? 1 : 0))
+ row = (int)((buttons.size()-buttons_pair_nb)/buttons_box.x) - (int)buttons_box.y +
+ ((int)(buttons.size()-buttons_pair_nb)%(int)buttons_box.x != 0 ? 1 : 0);
+ }
+ else if(event.button.button == SDL_BUTTON_LEFT)
+ mouse_left_button = true;
+ else
+ caught_event = false;
+ break;
+ case SDL_MOUSEBUTTONUP:
+ mouse_left_button = false;
+ break;
+ default:
+ break;
+ }
+
+ if(caught_event)
+ return true;
+
+ for(Buttons::iterator i = buttons.begin(); i != buttons.end(); ++i)
+ {
+ if(i->pos.y < row*buttons_size.y ||
+ i->pos.y + i->size.y > (row + buttons_box.y) * buttons_size.y)
+ continue;
+
+ if(i->event(event, (int)pos.x,
+ (int)pos.y - row*(int)buttons_size.y) == BT_SELECTED)
+ {
+ button_selected = i->id;
+ caught_event = true;
+ break;
+ }
+ }
+
+ return caught_event;
+}
+
+int
+ButtonGroup::selected_id()
+{
+ return button_selected;
+}
+
+void
+ButtonGroup::set_unselected()
+{
+ button_selected = -1;
+}
+
+bool
+ButtonGroup::is_hover()
+{
+ return mouse_hover;
+}
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_GUI_BUTTON_GROUP_HPP
+#define HEADER_SUPERTUX_GUI_BUTTON_GROUP_HPP
+
+#include <SDL.h>
+#include <string>
+#include <vector>
+
+#include "math/vector.hpp"
+#include "gui/button.hpp"
+
+class DrawingContext;
+
+class ButtonGroup
+{
+public:
+ ButtonGroup(Vector pos_, Vector size_, Vector button_box_);
+ ~ButtonGroup();
+
+ void draw(DrawingContext& context);
+ bool event(SDL_Event& event);
+
+ void add_button(Button button, int id, bool select = false);
+ void add_pair_of_buttons(Button button1, int id1, Button button2, int id2);
+
+ int selected_id();
+ void set_unselected();
+ bool is_hover();
+
+private:
+ Vector pos, buttons_size, buttons_box;
+ typedef std::vector <Button> Buttons;
+ Buttons buttons;
+
+ int button_selected, row;
+ bool mouse_hover, mouse_left_button;
+
+ int buttons_pair_nb;
+
+private:
+ ButtonGroup(const ButtonGroup&);
+ ButtonGroup& operator=(const ButtonGroup&);
+};
+
+#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
-
-#include <sys/types.h>
-#include <ctype.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <iostream>
-#include <sstream>
#include <math.h>
-#include <cstdlib>
-#include <cstdio>
-#include <string>
-#include <cassert>
-#include <stdexcept>
-
-#include "menu.hpp"
-#include "mainloop.hpp"
-#include "video/drawing_context.hpp"
-#include "gettext.hpp"
-#include "math/vector.hpp"
-#include "main.hpp"
-#include "resources.hpp"
-#include "timer.hpp"
+
#include "control/joystickkeyboardcontroller.hpp"
+#include "gui/menu.hpp"
+#include "supertux/main.hpp"
+#include "supertux/mainloop.hpp"
+#include "supertux/resources.hpp"
+#include "supertux/timer.hpp"
+#include "util/gettext.hpp"
+#include "video/drawing_context.hpp"
static const float MENU_REPEAT_INITIAL = 0.4f;
static const float MENU_REPEAT_RATE = 0.1f;
static const float FLICK_CURSOR_TIME = 0.5f;
-extern SDL_Surface* screen;
+extern SDL_Surface* g_screen;
std::vector<Menu*> Menu::last_menus;
std::list<Menu*> Menu::all_menus;
// TODO make this a screen and not another mainloop...
while(true)
- {
- SDL_Event event;
- while (SDL_PollEvent(&event)) {
- if(event.type == SDL_QUIT)
- main_loop->quit();
- main_controller->process_event(event);
- dialog->event(event);
- }
-
- if(background == NULL)
- context.draw_gradient(Color(0.8f, 0.95f, 0.85f), Color(0.8f, 0.8f, 0.8f),
- LAYER_BACKGROUND0);
- else
- context.draw_surface(background, Vector(0,0), LAYER_BACKGROUND0);
+ {
+ SDL_Event event;
+ while (SDL_PollEvent(&event)) {
+ if(event.type == SDL_QUIT)
+ g_main_loop->quit();
+ g_main_controller->process_event(event);
+ dialog->event(event);
+ }
- dialog->draw(context);
- dialog->update();
+ if(background == NULL)
+ context.draw_gradient(Color(0.8f, 0.95f, 0.85f), Color(0.8f, 0.8f, 0.8f),
+ LAYER_BACKGROUND0);
+ else
+ context.draw_surface(background, Vector(0,0), LAYER_BACKGROUND0);
- switch (dialog->check())
- {
- case true:
- //delete cap_screen;
- Menu::set_current(0);
- delete dialog;
- return true;
- break;
- case false:
- //delete cap_screen;
- Menu::set_current(0);
- delete dialog;
- return false;
- break;
- default:
- break;
- }
+ dialog->draw(context);
+ dialog->update();
- mouse_cursor->draw(context);
- context.do_drawing();
- SDL_Delay(25);
+ switch (dialog->check())
+ {
+ case true:
+ //delete cap_screen;
+ Menu::set_current(0);
+ delete dialog;
+ return true;
+ break;
+ case false:
+ //delete cap_screen;
+ Menu::set_current(0);
+ delete dialog;
+ return false;
+ break;
+ default:
+ break;
}
+ mouse_cursor->draw(context);
+ context.do_drawing();
+ SDL_Delay(25);
+ }
+
return false;
}
current_ = menu;
}
else if (current_) {
- last_menus.clear(); //NULL new menu pointer => close all menus
+ last_menus.clear(); //NULL new menu pointer => close all menus
current_->effect_start_time = real_time;
current_->effect_progress = 0.0f;
current_->close = true;
}
// just to be sure...
- main_controller->reset();
+ g_main_controller->reset();
}
void
current_->set_pos(SCREEN_WIDTH/2, SCREEN_HEIGHT/2);
for(std::list<Menu*>::iterator i = all_menus.begin(); i != all_menus.end(); ++i)
- {
- // FIXME: This is of course not quite right, since it ignores any previous set_pos() calls
- (*i)->set_pos(SCREEN_WIDTH/2, SCREEN_HEIGHT/2);
- }
+ {
+ // FIXME: This is of course not quite right, since it ignores any previous set_pos() calls
+ (*i)->set_pos(SCREEN_WIDTH/2, SCREEN_HEIGHT/2);
+ }
}
MenuItem::MenuItem(MenuItemKind _kind, int _id)
std::string overflow;
help = normal_font->wrap_to_width(help_text, 600, &overflow);
while (!overflow.empty())
- {
- help += "\n";
- help += normal_font->wrap_to_width(overflow, 600, &overflow);
- }
+ {
+ help += "\n";
+ help += normal_font->wrap_to_width(overflow, 600, &overflow);
+ }
}
std::string MenuItem::get_input_with_symbol(bool active_item)
}
Menu::Menu()
- : close(false)
+ : close(false)
{
all_menus.push_back(this);
MenuItem*
Menu::add_controlfield(int id, const std::string& text,
- const std::string& mapping)
+ const std::string& mapping)
{
MenuItem* item = new MenuItem(MN_CONTROLFIELD, id);
item->change_text(text);
- item->change_input(mapping);
+ item->change_input(mapping);
additem(item);
return item;
}
{
int menu_height = (int) get_height();
if (menu_height > SCREEN_HEIGHT)
- { // Scrolling
- int scroll_offset = (menu_height - SCREEN_HEIGHT) / 2 + 32;
- pos_y = SCREEN_HEIGHT/2 - scroll_offset * ((float(active_item) / (items.size()-1)) - 0.5f) * 2.0f;
- }
+ { // Scrolling
+ int scroll_offset = (menu_height - SCREEN_HEIGHT) / 2 + 32;
+ pos_y = SCREEN_HEIGHT/2 - scroll_offset * ((float(active_item) / (items.size()-1)) - 0.5f) * 2.0f;
+ }
effect_progress = (real_time - effect_start_time) * 6.0f;
}
/** check main input controller... */
- if(main_controller->pressed(Controller::UP)) {
+ if(g_main_controller->pressed(Controller::UP)) {
menuaction = MENU_ACTION_UP;
menu_repeat_time = real_time + MENU_REPEAT_INITIAL;
}
- if(main_controller->hold(Controller::UP) &&
- menu_repeat_time != 0 && real_time > menu_repeat_time) {
+ if(g_main_controller->hold(Controller::UP) &&
+ menu_repeat_time != 0 && real_time > menu_repeat_time) {
menuaction = MENU_ACTION_UP;
menu_repeat_time = real_time + MENU_REPEAT_RATE;
}
- if(main_controller->pressed(Controller::DOWN)) {
+ if(g_main_controller->pressed(Controller::DOWN)) {
menuaction = MENU_ACTION_DOWN;
menu_repeat_time = real_time + MENU_REPEAT_INITIAL;
}
- if(main_controller->hold(Controller::DOWN) &&
- menu_repeat_time != 0 && real_time > menu_repeat_time) {
+ if(g_main_controller->hold(Controller::DOWN) &&
+ menu_repeat_time != 0 && real_time > menu_repeat_time) {
menuaction = MENU_ACTION_DOWN;
menu_repeat_time = real_time + MENU_REPEAT_RATE;
}
- if(main_controller->pressed(Controller::LEFT)) {
+ if(g_main_controller->pressed(Controller::LEFT)) {
menuaction = MENU_ACTION_LEFT;
menu_repeat_time = real_time + MENU_REPEAT_INITIAL;
}
- if(main_controller->hold(Controller::LEFT) &&
- menu_repeat_time != 0 && real_time > menu_repeat_time) {
+ if(g_main_controller->hold(Controller::LEFT) &&
+ menu_repeat_time != 0 && real_time > menu_repeat_time) {
menuaction = MENU_ACTION_LEFT;
menu_repeat_time = real_time + MENU_REPEAT_RATE;
}
- if(main_controller->pressed(Controller::RIGHT)) {
+ if(g_main_controller->pressed(Controller::RIGHT)) {
menuaction = MENU_ACTION_RIGHT;
menu_repeat_time = real_time + MENU_REPEAT_INITIAL;
}
- if(main_controller->hold(Controller::RIGHT) &&
- menu_repeat_time != 0 && real_time > menu_repeat_time) {
+ if(g_main_controller->hold(Controller::RIGHT) &&
+ menu_repeat_time != 0 && real_time > menu_repeat_time) {
menuaction = MENU_ACTION_RIGHT;
menu_repeat_time = real_time + MENU_REPEAT_RATE;
}
- if(main_controller->pressed(Controller::ACTION)
- || main_controller->pressed(Controller::MENU_SELECT)) {
+ if(g_main_controller->pressed(Controller::ACTION)
+ || g_main_controller->pressed(Controller::MENU_SELECT)) {
menuaction = MENU_ACTION_HIT;
}
- if(main_controller->pressed(Controller::PAUSE_MENU)) {
+ if(g_main_controller->pressed(Controller::PAUSE_MENU)) {
menuaction = MENU_ACTION_BACK;
}
case MN_STRINGSELECT:
if(items[active_item]->selected+1 < items[active_item]->list.size())
- items[active_item]->selected++;
+ items[active_item]->selected++;
else
items[active_item]->selected = 0;
{
if (hit_item != -1) {
int id = items[hit_item]->id;
- hit_item = -1; //Clear event when checked out.. (we would end up in a loop when we try to leave "fake" submenu like Addons or Contrib)
+ hit_item = -1; //Clear event when checked out.. (we would end up in a loop when we try to leave "fake" submenu like Addons or Contrib)
return id;
}
else
x_pos += 24 - menu_width/2 + (text_width + input_width + list_width)/2;
if(index == active_item)
- {
- shadow_size = 3;
- text_color = active_color;
- }
+ {
+ shadow_size = 3;
+ text_color = active_color;
+ }
if(active_item == index)
- {
- float blink = (sinf(real_time * M_PI * 1.0f)/2.0f + 0.5f) * 0.5f + 0.25f;
- context.draw_filled_rect(Rect(Vector(pos_x - menu_width/2 + 10 - 2, y_pos - 12 - 2),
- Vector(pos_x + menu_width/2 - 10 + 2, y_pos + 12 + 2)),
- Color(1.0f, 1.0f, 1.0f, blink),
- 14.0f,
- LAYER_GUI-10);
- context.draw_filled_rect(Rect(Vector(pos_x - menu_width/2 + 10, y_pos - 12),
- Vector(pos_x + menu_width/2 - 10, y_pos + 12)),
- Color(1.0f, 1.0f, 1.0f, 0.5f),
- 12.0f,
- LAYER_GUI-10);
- }
+ {
+ float blink = (sinf(real_time * M_PI * 1.0f)/2.0f + 0.5f) * 0.5f + 0.25f;
+ context.draw_filled_rect(Rect(Vector(pos_x - menu_width/2 + 10 - 2, y_pos - 12 - 2),
+ Vector(pos_x + menu_width/2 - 10 + 2, y_pos + 12 + 2)),
+ Color(1.0f, 1.0f, 1.0f, blink),
+ 14.0f,
+ LAYER_GUI-10);
+ context.draw_filled_rect(Rect(Vector(pos_x - menu_width/2 + 10, y_pos - 12),
+ Vector(pos_x + menu_width/2 - 10, y_pos + 12)),
+ Color(1.0f, 1.0f, 1.0f, 0.5f),
+ 12.0f,
+ LAYER_GUI-10);
+ }
switch (pitem.kind)
- {
+ {
case MN_INACTIVE:
- {
- context.draw_text(normal_font, pitem.text,
- Vector(pos_x, y_pos - int(normal_font->get_height()/2)),
- ALIGN_CENTER, LAYER_GUI, inactive_color);
- break;
- }
+ {
+ context.draw_text(normal_font, pitem.text,
+ Vector(pos_x, y_pos - int(normal_font->get_height()/2)),
+ ALIGN_CENTER, LAYER_GUI, inactive_color);
+ break;
+ }
case MN_HL:
- {
- // TODO
- float x = pos_x - menu_width/2;
- float y = y_pos - 12;
- /* Draw a horizontal line with a little 3d effect */
- context.draw_filled_rect(Vector(x, y + 6),
- Vector(menu_width, 4),
- Color(0.6f, 0.7f, 1.0f, 1.0f), LAYER_GUI);
- context.draw_filled_rect(Vector(x, y + 6),
- Vector(menu_width, 2),
- Color(1.0f, 1.0f, 1.0f, 1.0f), LAYER_GUI);
- break;
- }
+ {
+ // TODO
+ float x = pos_x - menu_width/2;
+ float y = y_pos - 12;
+ /* Draw a horizontal line with a little 3d effect */
+ context.draw_filled_rect(Vector(x, y + 6),
+ Vector(menu_width, 4),
+ Color(0.6f, 0.7f, 1.0f, 1.0f), LAYER_GUI);
+ context.draw_filled_rect(Vector(x, y + 6),
+ Vector(menu_width, 2),
+ Color(1.0f, 1.0f, 1.0f, 1.0f), LAYER_GUI);
+ break;
+ }
case MN_LABEL:
- {
- context.draw_text(big_font, pitem.text,
- Vector(pos_x, y_pos - int(big_font->get_height()/2)),
- ALIGN_CENTER, LAYER_GUI, label_color);
- break;
- }
+ {
+ context.draw_text(big_font, pitem.text,
+ Vector(pos_x, y_pos - int(big_font->get_height()/2)),
+ ALIGN_CENTER, LAYER_GUI, label_color);
+ break;
+ }
case MN_TEXTFIELD:
case MN_NUMFIELD:
case MN_CONTROLFIELD:
+ {
+ if(pitem.kind == MN_TEXTFIELD || pitem.kind == MN_NUMFIELD)
{
- if(pitem.kind == MN_TEXTFIELD || pitem.kind == MN_NUMFIELD)
- {
- if(active_item == index)
- context.draw_text(normal_font,
- pitem.get_input_with_symbol(true),
- Vector(right, y_pos - int(normal_font->get_height()/2)),
- ALIGN_RIGHT, LAYER_GUI, field_color);
- else
- context.draw_text(normal_font,
- pitem.get_input_with_symbol(false),
- Vector(right, y_pos - int(normal_font->get_height()/2)),
- ALIGN_RIGHT, LAYER_GUI, field_color);
- }
+ if(active_item == index)
+ context.draw_text(normal_font,
+ pitem.get_input_with_symbol(true),
+ Vector(right, y_pos - int(normal_font->get_height()/2)),
+ ALIGN_RIGHT, LAYER_GUI, field_color);
else
- context.draw_text(normal_font, pitem.input,
+ context.draw_text(normal_font,
+ pitem.get_input_with_symbol(false),
Vector(right, y_pos - int(normal_font->get_height()/2)),
ALIGN_RIGHT, LAYER_GUI, field_color);
-
- context.draw_text(normal_font, pitem.text,
- Vector(left, y_pos - int(normal_font->get_height()/2)),
- ALIGN_LEFT, LAYER_GUI, text_color);
- break;
}
+ else
+ context.draw_text(normal_font, pitem.input,
+ Vector(right, y_pos - int(normal_font->get_height()/2)),
+ ALIGN_RIGHT, LAYER_GUI, field_color);
+
+ context.draw_text(normal_font, pitem.text,
+ Vector(left, y_pos - int(normal_font->get_height()/2)),
+ ALIGN_LEFT, LAYER_GUI, text_color);
+ break;
+ }
case MN_STRINGSELECT:
- {
- float roff = arrow_left->get_width();
- // Draw left side
- context.draw_text(normal_font, pitem.text,
- Vector(left, y_pos - int(normal_font->get_height()/2)),
- ALIGN_LEFT, LAYER_GUI, text_color);
-
- // Draw right side
- context.draw_surface(arrow_left.get(),
- Vector(right - list_width - roff - roff, y_pos - 8),
- LAYER_GUI);
- context.draw_surface(arrow_right.get(),
- Vector(right - roff, y_pos - 8),
- LAYER_GUI);
- context.draw_text(normal_font, pitem.list[pitem.selected],
- Vector(right - roff, y_pos - int(normal_font->get_height()/2)),
- ALIGN_RIGHT, LAYER_GUI, text_color);
- break;
- }
+ {
+ float roff = arrow_left->get_width();
+ // Draw left side
+ context.draw_text(normal_font, pitem.text,
+ Vector(left, y_pos - int(normal_font->get_height()/2)),
+ ALIGN_LEFT, LAYER_GUI, text_color);
+
+ // Draw right side
+ context.draw_surface(arrow_left.get(),
+ Vector(right - list_width - roff - roff, y_pos - 8),
+ LAYER_GUI);
+ context.draw_surface(arrow_right.get(),
+ Vector(right - roff, y_pos - 8),
+ LAYER_GUI);
+ context.draw_text(normal_font, pitem.list[pitem.selected],
+ Vector(right - roff, y_pos - int(normal_font->get_height()/2)),
+ ALIGN_RIGHT, LAYER_GUI, text_color);
+ break;
+ }
case MN_BACK:
- {
- context.draw_text(normal_font, pitem.text,
- Vector(pos_x, y_pos - int(normal_font->get_height()/2)),
- ALIGN_CENTER, LAYER_GUI, text_color);
- context.draw_surface(back.get(),
- Vector(x_pos + text_width/2 + 16, y_pos - 8),
- LAYER_GUI);
- break;
- }
+ {
+ context.draw_text(normal_font, pitem.text,
+ Vector(pos_x, y_pos - int(normal_font->get_height()/2)),
+ ALIGN_CENTER, LAYER_GUI, text_color);
+ context.draw_surface(back.get(),
+ Vector(x_pos + text_width/2 + 16, y_pos - 8),
+ LAYER_GUI);
+ break;
+ }
case MN_TOGGLE:
- {
- context.draw_text(normal_font, pitem.text,
- Vector(pos_x - menu_width/2 + 16, y_pos - (normal_font->get_height()/2)),
- ALIGN_LEFT, LAYER_GUI, text_color);
-
- if(pitem.toggled)
- context.draw_surface(checkbox_checked.get(),
- Vector(x_pos + (menu_width/2-16) - checkbox->get_width(), y_pos - 8),
- LAYER_GUI + 1);
- else
- context.draw_surface(checkbox.get(),
- Vector(x_pos + (menu_width/2-16) - checkbox->get_width(), y_pos - 8),
- LAYER_GUI + 1);
- break;
- }
+ {
+ context.draw_text(normal_font, pitem.text,
+ Vector(pos_x - menu_width/2 + 16, y_pos - (normal_font->get_height()/2)),
+ ALIGN_LEFT, LAYER_GUI, text_color);
+
+ if(pitem.toggled)
+ context.draw_surface(checkbox_checked.get(),
+ Vector(x_pos + (menu_width/2-16) - checkbox->get_width(), y_pos - 8),
+ LAYER_GUI + 1);
+ else
+ context.draw_surface(checkbox.get(),
+ Vector(x_pos + (menu_width/2-16) - checkbox->get_width(), y_pos - 8),
+ LAYER_GUI + 1);
+ break;
+ }
case MN_ACTION:
context.draw_text(normal_font, pitem.text,
Vector(pos_x, y_pos - int(normal_font->get_height()/2)),
Vector(pos_x, y_pos - int(normal_font->get_height()/2)),
ALIGN_CENTER, LAYER_GUI, text_color);
break;
- }
+ }
}
float
font = big_font;
float w = font->get_text_width(items[i]->text) +
- big_font->get_text_width(items[i]->input) + 16;
+ big_font->get_text_width(items[i]->input) + 16;
if(items[i]->kind == MN_TOGGLE)
w += 32;
float menu_height = get_height();
if (effect_progress != 1.0f)
+ {
+ if (close)
{
- if (close)
- {
- menu_width = (current_->get_width() * (1.0f - effect_progress));
- menu_height = (current_->get_height() * (1.0f - effect_progress));
- }
- else if (Menu::previous)
- {
- menu_width = (menu_width * effect_progress) + (Menu::previous->get_width() * (1.0f - effect_progress));
- menu_height = (menu_height * effect_progress) + (Menu::previous->get_height() * (1.0f - effect_progress));
- //std::cout << effect_progress << " " << this << " " << last_menus.back() << std::endl;
- }
- else
- {
- menu_width *= effect_progress;
- menu_height *= effect_progress;
- }
+ menu_width = (current_->get_width() * (1.0f - effect_progress));
+ menu_height = (current_->get_height() * (1.0f - effect_progress));
+ }
+ else if (Menu::previous)
+ {
+ menu_width = (menu_width * effect_progress) + (Menu::previous->get_width() * (1.0f - effect_progress));
+ menu_height = (menu_height * effect_progress) + (Menu::previous->get_height() * (1.0f - effect_progress));
+ //std::cout << effect_progress << " " << this << " " << last_menus.back() << std::endl;
+ }
+ else
+ {
+ menu_width *= effect_progress;
+ menu_height *= effect_progress;
}
+ }
/* Draw a transparent background */
context.draw_filled_rect(Rect(Vector(pos_x - menu_width/2-4, pos_y - menu_height/2 - 10-4),
LAYER_GUI-10);
if (!items[active_item]->help.empty())
- {
- int text_width = (int) normal_font->get_text_width(items[active_item]->help);
- int text_height = (int) normal_font->get_text_height(items[active_item]->help);
+ {
+ int text_width = (int) normal_font->get_text_width(items[active_item]->help);
+ int text_height = (int) normal_font->get_text_height(items[active_item]->help);
- Rect text_rect(pos_x - text_width/2 - 8,
- SCREEN_HEIGHT - 48 - text_height/2 - 4,
- pos_x + text_width/2 + 8,
- SCREEN_HEIGHT - 48 + text_height/2 + 4);
+ Rect text_rect(pos_x - text_width/2 - 8,
+ SCREEN_HEIGHT - 48 - text_height/2 - 4,
+ pos_x + text_width/2 + 8,
+ SCREEN_HEIGHT - 48 + text_height/2 + 4);
- context.draw_filled_rect(Rect(text_rect.p1 - Vector(4,4),
- text_rect.p2 + Vector(4,4)),
- Color(0.2f, 0.3f, 0.4f, 0.8f),
- 16.0f,
- LAYER_GUI-10);
+ context.draw_filled_rect(Rect(text_rect.p1 - Vector(4,4),
+ text_rect.p2 + Vector(4,4)),
+ Color(0.2f, 0.3f, 0.4f, 0.8f),
+ 16.0f,
+ LAYER_GUI-10);
- context.draw_filled_rect(text_rect,
- Color(0.6f, 0.7f, 0.8f, 0.5f),
- 16.0f,
- LAYER_GUI-10);
-
- context.draw_text(normal_font, items[active_item]->help,
- Vector(pos_x, SCREEN_HEIGHT - 48 - text_height/2),
- ALIGN_CENTER, LAYER_GUI);
- }
+ context.draw_filled_rect(text_rect,
+ Color(0.6f, 0.7f, 0.8f, 0.5f),
+ 16.0f,
+ LAYER_GUI-10);
+
+ context.draw_text(normal_font, items[active_item]->help,
+ Vector(pos_x, SCREEN_HEIGHT - 48 - text_height/2),
+ ALIGN_CENTER, LAYER_GUI);
+ }
if (effect_progress == 1.0f)
for(unsigned int i = 0; i < items.size(); ++i)
- {
- draw_item(context, i);
- }
+ {
+ draw_item(context, i);
+ }
}
MenuItem&
switch(event.type) {
case SDL_MOUSEBUTTONDOWN:
- {
- int x = int(event.motion.x * float(SCREEN_WIDTH)/screen->w);
- int y = int(event.motion.y * float(SCREEN_HEIGHT)/screen->h);
+ {
+ int x = int(event.motion.x * float(SCREEN_WIDTH)/g_screen->w);
+ int y = int(event.motion.y * float(SCREEN_HEIGHT)/g_screen->h);
- if(x > pos_x - get_width()/2 &&
- x < pos_x + get_width()/2 &&
- y > pos_y - get_height()/2 &&
- y < pos_y + get_height()/2)
- {
- menuaction = MENU_ACTION_HIT;
- }
+ if(x > pos_x - get_width()/2 &&
+ x < pos_x + get_width()/2 &&
+ y > pos_y - get_height()/2 &&
+ y < pos_y + get_height()/2)
+ {
+ menuaction = MENU_ACTION_HIT;
}
- break;
+ }
+ break;
case SDL_MOUSEMOTION:
- {
- float x = event.motion.x * SCREEN_WIDTH/screen->w;
- float y = event.motion.y * SCREEN_HEIGHT/screen->h;
+ {
+ float x = event.motion.x * SCREEN_WIDTH/g_screen->w;
+ float y = event.motion.y * SCREEN_HEIGHT/g_screen->h;
- if(x > pos_x - get_width()/2 &&
- x < pos_x + get_width()/2 &&
- y > pos_y - get_height()/2 &&
- y < pos_y + get_height()/2)
- {
- int new_active_item
- = static_cast<int> ((y - (pos_y - get_height()/2)) / 24);
+ if(x > pos_x - get_width()/2 &&
+ x < pos_x + get_width()/2 &&
+ y > pos_y - get_height()/2 &&
+ y < pos_y + get_height()/2)
+ {
+ int new_active_item
+ = static_cast<int> ((y - (pos_y - get_height()/2)) / 24);
- /* only change the mouse focus to a selectable item */
- if ((items[new_active_item]->kind != MN_HL)
- && (items[new_active_item]->kind != MN_LABEL)
- && (items[new_active_item]->kind != MN_INACTIVE))
- active_item = new_active_item;
+ /* only change the mouse focus to a selectable item */
+ if ((items[new_active_item]->kind != MN_HL)
+ && (items[new_active_item]->kind != MN_LABEL)
+ && (items[new_active_item]->kind != MN_INACTIVE))
+ active_item = new_active_item;
- if(MouseCursor::current())
- MouseCursor::current()->set_state(MC_LINK);
- }
- else
- {
- if(MouseCursor::current())
- MouseCursor::current()->set_state(MC_NORMAL);
- }
+ if(MouseCursor::current())
+ MouseCursor::current()->set_state(MC_LINK);
}
- break;
+ else
+ {
+ if(MouseCursor::current())
+ MouseCursor::current()->set_state(MC_NORMAL);
+ }
+ }
+ break;
default:
break;
- }
+ }
}
void
}
}
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef SUPERTUX_MENU_H
-#define SUPERTUX_MENU_H
+#ifndef HEADER_SUPERTUX_GUI_MENU_HPP
+#define HEADER_SUPERTUX_GUI_MENU_HPP
-#include <vector>
#include <list>
#include <memory>
-#include <set>
-#include <string>
-#include <utility>
-#include <assert.h>
-
#include <SDL.h>
-#include "video/surface.hpp"
+#include "gui/mousecursor.hpp"
#include "video/font.hpp"
-#include "mousecursor.hpp"
bool confirm_dialog(Surface* background, std::string text);
MN_CONTROLFIELD,
MN_STRINGSELECT,
MN_LABEL,
- MN_HL, /* horizontal line */
+ MN_HL /* horizontal line */
};
class Menu;
std::string get_input_with_symbol(bool active_item); // returns the text with an input symbol
private:
- /// copy-construction not allowed
- MenuItem(const MenuItem& ) { assert(false); }
- /// assignment not allowed
- void operator= (const MenuItem& ) { assert(false); }
-
/// keyboard key or joystick button
bool input_flickering;
+
+private:
+ MenuItem(const MenuItem&);
+ MenuItem& operator=(const MenuItem&);
};
class Menu
static void push_current(Menu* pmenu);
static void pop_current();
-
static void recalc_pos();
/** Return the current active menu or NULL if none is active */
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "gui/mousecursor.hpp"
-#include <SDL_events.h>
-#include <SDL_mouse.h>
+#include <SDL.h>
-#include "video/surface.hpp"
+#include "supertux/main.hpp"
#include "video/drawing_context.hpp"
-#include "main.hpp"
MouseCursor* MouseCursor::current_ = 0;
-extern SDL_Surface* screen;
+extern SDL_Surface* g_screen;
MouseCursor::MouseCursor(std::string cursor_file) : mid_x(0), mid_y(0)
{
int x,y,w,h;
Uint8 ispressed = SDL_GetMouseState(&x,&y);
- x = int(x * float(SCREEN_WIDTH)/screen->w);
- y = int(y * float(SCREEN_HEIGHT)/screen->h);
+ x = int(x * float(SCREEN_WIDTH)/g_screen->w);
+ y = int(y * float(SCREEN_HEIGHT)/g_screen->h);
w = (int) cursor->get_width();
h = (int) (cursor->get_height() / MC_STATES_NB);
}
context.draw_surface_part(cursor, Vector(0, h*cur_state),
- Vector(w, h), Vector(x-mid_x, y-mid_y), LAYER_GUI+100);
+ Vector(w, h), Vector(x-mid_x, y-mid_y), LAYER_GUI+100);
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef SUPERTUX_MOUSECURSOR_H
-#define SUPERTUX_MOUSECURSOR_H
+#ifndef HEADER_SUPERTUX_GUI_MOUSECURSOR_HPP
+#define HEADER_SUPERTUX_GUI_MOUSECURSOR_HPP
#include <string>
int state_before_click;
int cur_state;
Surface* cursor;
+
+private:
+ MouseCursor(const MouseCursor&);
+ MouseCursor& operator=(const MouseCursor&);
};
#endif /*SUPERTUX_MOUSECURSOR_H*/
+
+/* EOF */
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-#include <config.h>
-
-#include "level.hpp"
-
-#include <map>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <iostream>
-#include <fstream>
-#include <sstream>
-#include <memory>
-#include <stdexcept>
-
-#include "log.hpp"
-#include "lisp/parser.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/list_iterator.hpp"
-#include "lisp/writer.hpp"
-#include "sector.hpp"
-#include "tile_set.hpp"
-#include "tile_manager.hpp"
-#include "object/coin.hpp"
-#include "object/block.hpp"
-#include "trigger/secretarea_trigger.hpp"
-
-using namespace std;
-
-Level::Level()
- : name("noname"), author("Mr. X"), tileset(NULL), free_tileset(false)
-{
-}
-
-Level::~Level()
-{
- for(Sectors::iterator i = sectors.begin(); i != sectors.end(); ++i)
- delete *i;
- if(free_tileset)
- delete tileset;
-}
-
-void
-Level::load(const std::string& filepath)
-{
- try {
- filename = filepath;
- lisp::Parser parser;
- const lisp::Lisp* root = parser.parse(filepath);
-
- const lisp::Lisp* level = root->get_lisp("supertux-level");
- if(!level)
- throw std::runtime_error("file is not a supertux-level file.");
-
- int version = 1;
- level->get("version", version);
- if(version == 1) {
- log_info << "level uses old format: version 1" << std::endl;
- tileset = tile_manager->get_tileset("images/tiles.strf");
- load_old_format(*level);
- return;
- }
-
- const lisp::Lisp* tilesets_lisp = level->get_lisp("tilesets");
- if(tilesets_lisp != NULL) {
- tileset = tile_manager->parse_tileset_definition(*tilesets_lisp);
- free_tileset = true;
- }
- std::string tileset_name;
- if(level->get("tileset", tileset_name)) {
- if(tileset != NULL) {
- log_warning << "multiple tilesets specified in level" << std::endl;
- } else {
- tileset = tile_manager->get_tileset(tileset_name);
- }
- }
- /* load default tileset */
- if(tileset == NULL) {
- tileset = tile_manager->get_tileset("images/tiles.strf");
- }
- current_tileset = tileset;
-
- contact = "";
- license = "";
-
- lisp::ListIterator iter(level);
- while(iter.next()) {
- const std::string& token = iter.item();
- if(token == "version") {
- iter.value()->get(version);
- if(version > 2) {
- log_warning << "level format newer than application" << std::endl;
- }
- } else if(token == "tileset" || token == "tilesets") {
- continue;
- } else if(token == "name") {
- iter.value()->get(name);
- } else if(token == "author") {
- iter.value()->get(author);
- } else if(token == "contact") {
- iter.value()->get(contact);
- } else if(token == "license") {
- iter.value()->get(license);
- } else if(token == "on-menukey-script") {
- iter.value()->get(on_menukey_script);
- } else if(token == "sector") {
- Sector* sector = new Sector(this);
- sector->parse(*(iter.lisp()));
- add_sector(sector);
- } else {
- log_warning << "Unknown token '" << token << "' in level file" << std::endl;
- }
- }
-
- if (license == "") {
- log_warning << "The level author did not specify a license for this level. You might not be allowed to share it." << std::endl;
-
- }
- } catch(std::exception& e) {
- std::stringstream msg;
- msg << "Problem when reading level '" << filepath << "': " << e.what();
- throw std::runtime_error(msg.str());
- }
-
- current_tileset = NULL;
-}
-
-void
-Level::load_old_format(const lisp::Lisp& reader)
-{
- reader.get("name", name);
- reader.get("author", author);
-
- Sector* sector = new Sector(this);
- sector->parse_old_format(reader);
- add_sector(sector);
-}
-
-void
-Level::save(const std::string& filename)
-{
- lisp::Writer* writer = new lisp::Writer(filename);
-
- writer->write_comment("Level made using SuperTux's built-in Level Editor");
-
- writer->start_list("supertux-level");
-
- int version = 2;
- writer->write("version", version);
-
- writer->write("name", name, true);
- writer->write("author", author);
- if(on_menukey_script != "")
- writer->write("on-menukey-script", on_menukey_script);
-
- for(Sectors::iterator i = sectors.begin(); i != sectors.end(); ++i) {
- Sector* sector = *i;
- writer->start_list("sector");
- sector->write(*writer);
- writer->end_list("sector");
- }
-
- writer->end_list("supertux-level");
-
- delete writer;
-}
-
-void
-Level::add_sector(Sector* sector)
-{
- Sector* test = get_sector(sector->get_name());
- if(test != 0) {
- throw std::runtime_error("Trying to add 2 sectors with same name");
- }
- sectors.push_back(sector);
-}
-
-Sector*
-Level::get_sector(const std::string& name)
-{
- for(Sectors::iterator i = sectors.begin(); i != sectors.end(); ++i) {
- Sector* sector = *i;
- if(sector->get_name() == name)
- return sector;
- }
-
- return 0;
-}
-
-size_t
-Level::get_sector_count()
-{
- return sectors.size();
-}
-
-Sector*
-Level::get_sector(size_t num)
-{
- return sectors.at(num);
-}
-
-int
-Level::get_total_coins()
-{
- int total_coins = 0;
- for(Sectors::iterator i = sectors.begin(); i != sectors.end(); ++i) {
- Sector* sector = *i;
- for(Sector::GameObjects::iterator o = sector->gameobjects.begin();
- o != sector->gameobjects.end(); ++o) {
- Coin* coin = dynamic_cast<Coin*> (*o);
- if(coin)
- {
- total_coins++;
- continue;
- }
- BonusBlock *block = dynamic_cast<BonusBlock*> (*o);
- if(block)
- {
- if (block->contents == BonusBlock::CONTENT_COIN)
- {
- total_coins++;
- continue;
- }
-#if 0
- // FIXME: do we want this? q.v. src/object/oneup.cpp
- else if (block->contents == BonusBlock::CONTENT_1UP)
- {
- total_coins += 100;
- continue;
- }
-#endif
- }
- }
- }
- return total_coins;
-}
-
-int
-Level::get_total_badguys()
-{
- int total_badguys = 0;
- for(Sectors::iterator i = sectors.begin(); i != sectors.end(); ++i)
- total_badguys += (*i)->get_total_badguys();
- return total_badguys;
-}
-
-int
-Level::get_total_secrets()
-{
- int total_secrets = 0;
- for(Sectors::iterator i = sectors.begin(); i != sectors.end(); ++i)
- total_secrets += (*i)->get_total_count<SecretAreaTrigger>();
- return total_secrets;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-
-#ifndef SUPERTUX_LEVEL_H
-#define SUPERTUX_LEVEL_H
-
-#include <vector>
-#include <string>
-
-#include "statistics.hpp"
-
-namespace lisp {
-class Lisp;
-}
-
-class TileSet;
-class Sector;
-
-/**
- * Represents a collection of Sectors running in a single GameSession.
- *
- * Each Sector in turn contains GameObjects, e.g. Badguys and Players.
- */
-class Level
-{
-public:
- typedef std::vector<Sector*> Sectors;
-
- std::string name;
- std::string author;
- std::string contact;
- std::string license;
- std::string filename;
- std::string on_menukey_script;
- Sectors sectors;
- Statistics stats;
- TileSet *tileset;
- bool free_tileset;
-
-public:
- Level();
- ~Level();
-
- // loads a levelfile
- void load(const std::string& filename);
- void save(const std::string& filename);
-
- const std::string& get_name() const
- { return name; }
-
- const std::string& get_author() const
- { return author; }
-
- void add_sector(Sector* sector);
-
- Sector* get_sector(const std::string& name);
-
- size_t get_sector_count();
- Sector* get_sector(size_t num);
-
- const TileSet *get_tileset() const
- { return tileset; }
-
- int get_total_coins();
- int get_total_badguys();
- int get_total_secrets();
-
-private:
- void load_old_format(const lisp::Lisp& reader);
-};
-
-#endif /*SUPERTUX_LEVEL_H*/
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-
-#include <config.h>
-
-#include "level_transformer.hpp"
-#include "level.hpp"
-
-LevelTransformer::~LevelTransformer()
-{
-}
-
-void
-LevelTransformer::transform(Level* level)
-{
- for(size_t i = 0; i < level->get_sector_count(); ++i) {
- transform_sector(level->get_sector(i));
- }
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-
-#ifndef __LEVEL_TRANSFORMER_H__
-#define __LEVEL_TRANSFORMER_H__
-
-class Level;
-class Sector;
-
-/**
- * This class is an abstract interface for algorithms that transform levels in
- * some way before they are played.
- */
-class LevelTransformer
-{
-public:
- virtual ~LevelTransformer();
-
- /** transform a complete Level, the standard implementation just calls
- * transformSector on each sector in the level.
- */
- virtual void transform(Level* level);
-
- virtual void transform_sector(Sector* sector) = 0;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux -- LevelIntro screen
-// Copyright (C) 2008 Christoph Sommer <christoph.sommer@2008.expires.deltadevelopment.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-#include <config.h>
-
-#include "levelintro.hpp"
-
-#include <stdexcept>
-#include "log.hpp"
-#include "mainloop.hpp"
-#include "gettext.hpp"
-#include "resources.hpp"
-#include "video/drawing_context.hpp"
-#include "gui/menu.hpp"
-#include "main.hpp"
-#include "fadeout.hpp"
-#include "control/joystickkeyboardcontroller.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "random_generator.hpp"
-
-LevelIntro::LevelIntro(const Level* level, const Statistics* best_level_statistics)
- : level(level), best_level_statistics(best_level_statistics), player_sprite_py(0), player_sprite_vy(0)
-{
- player_sprite.reset(sprite_manager->create("images/creatures/tux/tux.sprite"));
- player_sprite->set_action("small-walk-right");
- player_sprite_jump_timer.start(systemRandom.randf(5,10));
-}
-
-LevelIntro::~LevelIntro()
-{
-}
-
-void
-LevelIntro::setup()
-{
-}
-
-void
-LevelIntro::update(float elapsed_time)
-{
-
- // Check if it's time to exit the screen
- if(main_controller->pressed(Controller::JUMP)
- || main_controller->pressed(Controller::ACTION)
- || main_controller->pressed(Controller::MENU_SELECT)
- || main_controller->pressed(Controller::PAUSE_MENU)) {
- main_loop->exit_screen(new FadeOut(0.1));
- }
-
- player_sprite_py += player_sprite_vy * elapsed_time;
- player_sprite_vy += 1000 * elapsed_time;
- if (player_sprite_py >= 0) {
- player_sprite_py = 0;
- player_sprite_vy = 0;
- }
- if (player_sprite_jump_timer.check()) {
- player_sprite_vy = -300;
- player_sprite_jump_timer.start(systemRandom.randf(2,3));
- }
-
-}
-
-void
-LevelIntro::draw(DrawingContext& context)
-{
- const Statistics& stats = level->stats;
- int py = static_cast<int>(SCREEN_HEIGHT / 2 - normal_font->get_height() / 2);
-
- context.draw_filled_rect(Vector(0, 0), Vector(SCREEN_WIDTH, SCREEN_HEIGHT), Color(0.0f, 0.0f, 0.0f, 1.0f), 0);
-
- {
- context.draw_center_text(normal_font, level->get_name(), Vector(0, py), LAYER_FOREGROUND1, LevelIntro::header_color);
- py += static_cast<int>(normal_font->get_height());
- }
-
- std::string author = level->get_author();
- if ((author != "") && (author != "SuperTux Team")) {
- std::string author_text = std::string(_("contributed by ")) + author;
- context.draw_center_text(small_font, author_text, Vector(0, py), LAYER_FOREGROUND1, LevelIntro::author_color);
- py += static_cast<int>(small_font->get_height());
- }
-
- py += 32;
-
- {
- player_sprite->draw(context, Vector((SCREEN_WIDTH - player_sprite->get_current_hitbox_width()) / 2, py + player_sprite_py), LAYER_FOREGROUND1);
- py += static_cast<int>(player_sprite->get_current_hitbox_height());
- }
-
- py += 32;
-
- {
- context.draw_center_text(normal_font, std::string("- ") + _("Best Level Statistics") + std::string(" -"), Vector(0, py), LAYER_FOREGROUND1, LevelIntro::stat_hdr_color);
- py += static_cast<int>(normal_font->get_height());
- }
-
- {
- std::stringstream ss;
- ss << _("Coins") << ": " << Statistics::coins_to_string((best_level_statistics && (best_level_statistics->coins >= 0)) ? best_level_statistics->coins : 0, stats.total_coins);
- context.draw_center_text(normal_font, ss.str(), Vector(0, py), LAYER_FOREGROUND1, LevelIntro::stat_color);
- py += static_cast<int>(normal_font->get_height());
- }
-
- {
- std::stringstream ss;
- ss << _("Secrets") << ": " << Statistics::secrets_to_string((best_level_statistics && (best_level_statistics->coins >= 0)) ? best_level_statistics->secrets : 0, stats.total_secrets);
- context.draw_center_text(normal_font, ss.str(), Vector(0, py), LAYER_FOREGROUND1,LevelIntro::stat_color);
- py += static_cast<int>(normal_font->get_height());
- }
-
- {
- std::stringstream ss;
- ss << _("Time") << ": " << Statistics::time_to_string((best_level_statistics && (best_level_statistics->coins >= 0)) ? best_level_statistics->time : 0);
- context.draw_center_text(normal_font, ss.str(), Vector(0, py), LAYER_FOREGROUND1,LevelIntro::stat_color);
- py += static_cast<int>(normal_font->get_height());
- }
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux -- LevelIntro screen
-// Copyright (C) 2008 Christoph Sommer <christoph.sommer@2008.expires.deltadevelopment.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-
-#ifndef __LEVELINTRO_H__
-#define __LEVELINTRO_H__
-
-#include <vector>
-#include <string>
-#include <map>
-#include <memory>
-
-#include "screen.hpp"
-#include "math/vector.hpp"
-#include "math/rect.hpp"
-#include "level.hpp"
-#include "sprite/sprite.hpp"
-#include "timer.hpp"
-
-class DrawingContext;
-class Surface;
-
-/**
- * Screen that welcomes the player to a level
- */
-class LevelIntro : public Screen
-{
- static Color header_color;
- static Color author_color;
- static Color stat_hdr_color;
- static Color stat_color;
-public:
- LevelIntro(const Level* level, const Statistics* best_level_statistics);
- virtual ~LevelIntro();
-
- void setup();
- void draw(DrawingContext& context);
- void update(float elapsed_time);
-
-private:
- const Level* level; /**< The level of which this is the intro screen */
- const Statistics* best_level_statistics; /**< Best level statistics of the level of which is the intro screen */
- std::auto_ptr<Sprite> player_sprite; /**< Sprite representing the player */
- float player_sprite_py; /**< Position (y axis) for the player sprite */
- float player_sprite_vy; /**< Velocity (y axis) for the player sprite */
- Timer player_sprite_jump_timer; /**< When timer fires, the player sprite will "jump" */
-};
-
-#endif
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#include "lisp/lexer.hpp"
-#include <sstream>
#include <cstring>
+#include <sstream>
#include <stdexcept>
-#include <iostream>
#include <stdio.h>
-#include "lexer.hpp"
-
-namespace lisp
-{
+namespace lisp {
Lexer::Lexer(std::istream& newstream)
- : stream(newstream), eof(false), linenumber(0)
+ : stream(newstream), eof(false), linenumber(0)
{
// trigger a refill of the buffer
bufpos = NULL;
while(1) {
nextChar();
switch(c) {
- case '"':
- nextChar();
- goto string_finished;
- case '\r':
- continue;
- case '\n':
- break;
- case '\\':
- nextChar();
- switch(c) {
- case 'n':
- c = '\n';
+ case '"':
+ nextChar();
+ goto string_finished;
+ case '\r':
+ continue;
+ case '\n':
break;
- case 't':
- c = '\t';
+ case '\\':
+ nextChar();
+ switch(c) {
+ case 'n':
+ c = '\n';
+ break;
+ case 't':
+ c = '\t';
+ break;
+ }
break;
+ case EOF: {
+ std::stringstream msg;
+ msg << "Parse error in line " << startline << ": "
+ << "EOF while parsing string.";
+ throw std::runtime_error(msg.str());
}
- break;
- case EOF: {
- std::stringstream msg;
- msg << "Parse error in line " << startline << ": "
- << "EOF while parsing string.";
- throw std::runtime_error(msg.str());
- }
- default:
- break;
+ default:
+ break;
}
if(token_length < MAX_TOKEN_LENGTH)
token_string[token_length++] = c;
}
-string_finished:
+ string_finished:
token_string[token_length] = 0;
return TOKEN_STRING;
}
}
} // end of namespace lisp
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#ifndef __LISPLEXER_H__
-#define __LISPLEXER_H__
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-namespace lisp
-{
+#ifndef HEADER_SUPERTUX_LISP_LEXER_HPP
+#define HEADER_SUPERTUX_LISP_LEXER_HPP
+
+#include <istream>
+
+namespace lisp {
class Lexer
{
int c;
char token_string[MAX_TOKEN_LENGTH + 1];
int token_length;
+
+private:
+ Lexer(const Lexer&);
+ Lexer & operator=(const Lexer&);
};
} // end of namespace lisp
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "lisp.hpp"
+#include "lisp/lisp.hpp"
#include <stdio.h>
-namespace lisp
-{
+namespace lisp {
Lisp::Lisp(LispType newtype)
: type(newtype)
}
} // end of namespace lisp
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __LISPREADER_H__
-#define __LISPREADER_H__
+#ifndef HEADER_SUPERTUX_LISP_LISP_HPP
+#define HEADER_SUPERTUX_LISP_LISP_HPP
+#include <assert.h>
#include <string>
#include <vector>
-#include <assert.h>
-namespace lisp
-{
+namespace lisp {
class Lisp
{
} // end of namespace lisp
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "list_iterator.hpp"
+#include "lisp/list_iterator.hpp"
#include <stdexcept>
-namespace lisp
-{
+namespace lisp {
ListIterator::ListIterator(const lisp::Lisp* newlisp)
: current_lisp(0), cur(newlisp)
throw std::runtime_error("Expected CONS");
const lisp::Lisp* name = child->get_car();
if(!name || (
- name->get_type() != lisp::Lisp::TYPE_SYMBOL
- && name->get_type() != lisp::Lisp::TYPE_STRING))
+ name->get_type() != lisp::Lisp::TYPE_SYMBOL
+ && name->get_type() != lisp::Lisp::TYPE_STRING))
throw std::runtime_error("Expected symbol");
name->get(current_item);
current_lisp = child->get_cdr();
}
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#ifndef __LISP_ITERATOR_H__
-#define __LISP_ITERATOR_H__
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <string>
+#ifndef HEADER_SUPERTUX_LISP_LIST_ITERATOR_HPP
+#define HEADER_SUPERTUX_LISP_LIST_ITERATOR_HPP
-#include "lisp.hpp"
+#include "lisp/lisp.hpp"
-namespace lisp
-{
+namespace lisp {
/**
* Small and a bit hacky helper class that helps parsing lisp lists where all
std::string current_item;
const lisp::Lisp* current_lisp;
const lisp::Lisp* cur;
+
+private:
+ ListIterator(const ListIterator&);
+ ListIterator& operator=(const ListIterator&);
};
}
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <sstream>
#include <stdexcept>
-#include <fstream>
-#include <cassert>
-#include <iostream>
-#include "tinygettext/tinygettext.hpp"
-#include "physfs/physfs_stream.hpp"
-#include "parser.hpp"
-#include "lisp.hpp"
+#include "lisp/lisp.hpp"
+#include "lisp/parser.hpp"
#include "obstack/obstackpp.hpp"
+#include "physfs/physfs_stream.hpp"
+#include "tinygettext/tinygettext.hpp"
-#include "gameconfig.hpp"
+#include "supertux/gameconfig.hpp"
-namespace lisp
-{
+namespace lisp {
Parser::Parser(bool translate)
: lexer(0), dictionary_manager(0), dictionary(0)
if(translate) {
dictionary_manager = new TinyGetText::DictionaryManager();
dictionary_manager->set_charset("UTF-8");
- if (config && (config->locale != "")) dictionary_manager->set_language(config->locale);
+ if (g_config && (g_config->locale != ""))
+ dictionary_manager->set_language(g_config->locale);
}
obstack_init(&obst);
}
if(token == Lexer::TOKEN_SYMBOL &&
- strcmp(lexer->getString(), "_") == 0) {
+ strcmp(lexer->getString(), "_") == 0) {
// evaluate translation function (_ str) in place here
token = lexer->getNextToken();
if(token != Lexer::TOKEN_STRING)
}
} // end of namespace lisp
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __LISPPARSER_H__
-#define __LISPPARSER_H__
+#ifndef HEADER_SUPERTUX_LISP_PARSER_HPP
+#define HEADER_SUPERTUX_LISP_PARSER_HPP
-#include <string>
-#include "lexer.hpp"
+#include "lisp/lexer.hpp"
#include "obstack/obstack.h"
namespace TinyGetText {
class DictionaryManager;
}
-namespace lisp
-{
+namespace lisp {
class Lisp;
class LispFile;
const Lisp* parse(std::istream& stream, const std::string& sourcename);
private:
- void parse_error(const char* msg) const;
+ void parse_error(const char* msg) const __attribute__((__noreturn__));
const Lisp* read();
Lexer* lexer;
Lexer::TokenType token;
struct obstack obst;
+
+private:
+ Parser(const Parser&);
+ Parser & operator=(const Parser&);
};
} // end of namespace lisp
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <iostream>
+#include "lisp/writer.hpp"
-#include "writer.hpp"
#include "physfs/physfs_stream.hpp"
-#include "log.hpp"
+#include "util/log.hpp"
-namespace lisp
-{
+namespace lisp {
Writer::Writer(const std::string& filename)
{
void
Writer::write(const std::string& name, const std::string& value,
- bool translatable)
+ bool translatable)
{
indent();
*out << '(' << name;
void
Writer::write(const std::string& name,
- const std::vector<int>& value)
+ const std::vector<int>& value)
{
indent();
*out << '(' << name;
void
Writer::write(const std::string& name,
- const std::vector<unsigned int>& value)
+ const std::vector<unsigned int>& value)
{
indent();
*out << '(' << name;
void
Writer::write(const std::string& name,
- const std::vector<float>& value)
+ const std::vector<float>& value)
{
indent();
*out << '(' << name;
void
Writer::write(const std::string& name,
- const std::vector<std::string>& value)
+ const std::vector<std::string>& value)
{
indent();
*out << '(' << name;
}
} // end of namespace lisp
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef SUPERTUX_LISPWRITER_H
-#define SUPERTUX_LISPWRITER_H
+#ifndef HEADER_SUPERTUX_LISP_WRITER_HPP
+#define HEADER_SUPERTUX_LISP_WRITER_HPP
-#include <iostream>
#include <string>
#include <vector>
-namespace lisp
+namespace lisp {
+
+class Writer
{
+public:
+ Writer(const std::string& filename);
+ Writer(std::ostream* out);
+ ~Writer();
- class Writer
- {
- public:
- Writer(const std::string& filename);
- Writer(std::ostream* out);
- ~Writer();
+ void write_comment(const std::string& comment);
- void write_comment(const std::string& comment);
+ void start_list(const std::string& listname, bool string = false);
- void start_list(const std::string& listname, bool string = false);
+ void write(const std::string& name, int value);
+ void write(const std::string& name, float value);
+ void write(const std::string& name, const std::string& value,
+ bool translatable = false);
+ void write(const std::string& name, const char* value,
+ bool translatable = false) { write(name, static_cast<const std::string&>(value), translatable); }
+ void write(const std::string& name, bool value);
+ void write(const std::string& name, const std::vector<int>& value);
+ void write(const std::string& name, const std::vector<unsigned int>& value);
+ void write(const std::string& name, const std::vector<float>& value);
+ void write(const std::string& name, const std::vector<std::string>& value);
+ // add more write-functions when needed...
- void write(const std::string& name, int value);
- void write(const std::string& name, float value);
- void write(const std::string& name, const std::string& value,
- bool translatable = false);
- void write(const std::string& name, const char* value,
- bool translatable = false) { write(name, static_cast<const std::string&>(value), translatable); }
- void write(const std::string& name, bool value);
- void write(const std::string& name, const std::vector<int>& value);
- void write(const std::string& name, const std::vector<unsigned int>& value);
- void write(const std::string& name, const std::vector<float>& value);
- void write(const std::string& name, const std::vector<std::string>& value);
- // add more write-functions when needed...
+ void end_list(const std::string& listname);
- void end_list(const std::string& listname);
+private:
+ void write_escaped_string(const std::string& str);
+ void indent();
- private:
- void write_escaped_string(const std::string& str);
- void indent();
+ std::ostream* out;
+ bool out_owned;
+ int indent_depth;
+ std::vector<std::string> lists;
- std::ostream* out;
- bool out_owned;
- int indent_depth;
- std::vector<std::string> lists;
- };
+private:
+ Writer(const Writer&);
+ Writer & operator=(const Writer&);
+};
} //namespace lisp
#endif //SUPERTUX_LISPWRITER_H
+
+/* EOF */
+++ /dev/null
-// $Id$
-//
-// SuperTux Debug Helper Functions
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-#include <config.h>
-
-#include "log.hpp"
-#include "math/vector.hpp"
-#include "math/rect.hpp"
-
-std::ostream& operator<<(std::ostream& out, const Vector& vector)
-{
- out << '[' << vector.x << ',' << vector.y << ']';
- return out;
-}
-
-std::ostream& operator<<(std::ostream& out, const Rect& rect)
-{
- out << "[" << rect.get_left() << "," << rect.get_top() << " "
- << rect.get_right() << "," << rect.get_bottom() << "]";
- return out;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux Debug Helper Functions
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-#ifndef __SUPERTUX_MSG_H__
-#define __SUPERTUX_MSG_H__
-
-#include <iostream>
-#include <stdio.h>
-
-#include "console.hpp"
-
-#ifdef DEBUG
-
-namespace {
-
-inline std::ostream& log_debug_f(const char* file, int line) {
- Console::output << "[DEBUG] " << file << ":" << line << " ";
- return Console::output;
-}
-
-inline std::ostream& log_info_f(const char* file, int line) {
- Console::output << "[INFO] " << file << ":" << line << " ";
- return Console::output;
-}
-
-inline std::ostream& log_warning_f(const char* file, int line) {
- Console::output << "[WARNING] " << file << ":" << line << " ";
- return Console::output;
-}
-
-inline std::ostream& log_fatal_f(const char* file, int line) {
- Console::output << "[FATAL] " << file << ":" << line << " ";
- return Console::output;
-}
-
-}
-
-#define log_debug log_debug_f(__FILE__, __LINE__)
-#define log_info log_info_f(__FILE__, __LINE__)
-#define log_warning log_warning_f(__FILE__, __LINE__)
-#define log_fatal log_fatal_f(__FILE__, __LINE__)
-
-#else
-
-namespace {
-
-inline std::ostream& log_fatal_f() {
- Console::output << "Fatal: ";
- return Console::output;
-}
-
-}
-
-#define log_debug if (0) std::cerr
-#define log_info std::cout
-#define log_warning std::cerr
-#define log_fatal log_fatal_f()
-
-#endif
-
-class Vector;
-std::ostream& operator<< (std::ostream& str, const Vector& vector);
-class Rect;
-std::ostream& operator<< (std::ostream& str, const Rect& rect);
-
-#endif
-// $Id$
-//
// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+// Copyright (C) 2009 Ingo Ruhnke <grumbel@gmx.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-#include <config.h>
-#include <version.h>
-#include <assert.h>
-
-#include "log.hpp"
-#include "main.hpp"
-
-#include <stdexcept>
-#include <sstream>
-#include <ctime>
-#include <cstdlib>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <physfs.h>
-#include <SDL.h>
-#include <SDL_image.h>
-
-#ifdef MACOSX
-namespace supertux_apple {
-#include <CoreFoundation/CoreFoundation.h>
-}
-#endif
-
-#include "gameconfig.hpp"
-#include "resources.hpp"
-#include "gettext.hpp"
-#include "audio/sound_manager.hpp"
-#include "video/surface.hpp"
-#include "video/texture_manager.hpp"
-#include "video/drawing_context.hpp"
-#include "video/glutil.hpp"
-#include "control/joystickkeyboardcontroller.hpp"
-#include "options_menu.hpp"
-#include "mainloop.hpp"
-#include "title.hpp"
-#include "game_session.hpp"
-#include "scripting/level.hpp"
-#include "scripting/squirrel_util.hpp"
-#include "file_system.hpp"
-#include "physfs/physfs_sdl.hpp"
-#include "random_generator.hpp"
-#include "worldmap/worldmap.hpp"
-#include "addon/addon_manager.hpp"
-#include "binreloc/binreloc.h"
-
-namespace { DrawingContext *context_pointer; }
-SDL_Surface *screen;
-JoystickKeyboardController* main_controller = 0;
-TinyGetText::DictionaryManager dictionary_manager;
-
-int SCREEN_WIDTH;
-int SCREEN_HEIGHT;
-
-static void init_config()
-{
- config = new Config();
- try {
- config->load();
- } catch(std::exception& e) {
- log_info << "Couldn't load config file: " << e.what() << ", using default settings" << std::endl;
- }
-}
-
-static void init_tinygettext()
-{
- dictionary_manager.add_directory("locale");
- dictionary_manager.set_charset("UTF-8");
-
- // Config setting "locale" overrides language detection
- if (config->locale != "") {
- dictionary_manager.set_language( config->locale );
- }
-}
-
-static void init_physfs(const char* argv0)
-{
- if(!PHYSFS_init(argv0)) {
- std::stringstream msg;
- msg << "Couldn't initialize physfs: " << PHYSFS_getLastError();
- throw std::runtime_error(msg.str());
- }
-
- // allow symbolic links
- PHYSFS_permitSymbolicLinks(1);
-
- // Initialize physfs (this is a slightly modified version of
- // PHYSFS_setSaneConfig
- const char* application = "supertux2"; //instead of PACKAGE_NAME so we can coexist with MS1
- const char* userdir = PHYSFS_getUserDir();
- char* writedir = new char[strlen(userdir) + strlen(application) + 2];
-
- // Set configuration directory
- sprintf(writedir, "%s.%s", userdir, application);
- if(!PHYSFS_setWriteDir(writedir)) {
- // try to create the directory
- char* mkdir = new char[strlen(application) + 2];
- sprintf(mkdir, ".%s", application);
- if(!PHYSFS_setWriteDir(userdir) || !PHYSFS_mkdir(mkdir)) {
- std::ostringstream msg;
- msg << "Failed creating configuration directory '"
- << writedir << "': " << PHYSFS_getLastError();
- delete[] writedir;
- delete[] mkdir;
- throw std::runtime_error(msg.str());
- }
- delete[] mkdir;
-
- if(!PHYSFS_setWriteDir(writedir)) {
- std::ostringstream msg;
- msg << "Failed to use configuration directory '"
- << writedir << "': " << PHYSFS_getLastError();
- delete[] writedir;
- throw std::runtime_error(msg.str());
- }
- }
- PHYSFS_addToSearchPath(writedir, 0);
- delete[] writedir;
-
- // when started from source dir...
- std::string dir = PHYSFS_getBaseDir();
- dir += "/data";
- std::string testfname = dir;
- testfname += "/credits.txt";
- bool sourcedir = false;
- FILE* f = fopen(testfname.c_str(), "r");
- if(f) {
- fclose(f);
- if(!PHYSFS_addToSearchPath(dir.c_str(), 1)) {
- log_warning << "Couldn't add '" << dir << "' to physfs searchpath: " << PHYSFS_getLastError() << std::endl;
- } else {
- sourcedir = true;
- }
- }
-
-#ifdef MACOSX
-{
- using namespace supertux_apple;
-
- // when started from Application file on Mac OS X...
- char path[PATH_MAX];
- CFBundleRef mainBundle = CFBundleGetMainBundle();
- assert(mainBundle != 0);
- CFURLRef mainBundleURL = CFBundleCopyBundleURL(mainBundle);
- assert(mainBundleURL != 0);
- CFStringRef pathStr = CFURLCopyFileSystemPath(mainBundleURL, kCFURLPOSIXPathStyle);
- assert(pathStr != 0);
- CFStringGetCString(pathStr, path, PATH_MAX, kCFStringEncodingUTF8);
- CFRelease(mainBundleURL);
- CFRelease(pathStr);
-
- dir = std::string(path) + "/Contents/Resources/data";
- testfname = dir + "/credits.txt";
- sourcedir = false;
- f = fopen(testfname.c_str(), "r");
- if(f) {
- fclose(f);
- if(!PHYSFS_addToSearchPath(dir.c_str(), 1)) {
- log_warning << "Couldn't add '" << dir << "' to physfs searchpath: " << PHYSFS_getLastError() << std::endl;
- } else {
- sourcedir = true;
- }
- }
-}
-#endif
-
-#ifdef _WIN32
- PHYSFS_addToSearchPath(".\\data", 1);
-#endif
-
- if(!sourcedir) {
-#if defined(APPDATADIR) || defined(ENABLE_BINRELOC)
- std::string datadir;
-#ifdef ENABLE_BINRELOC
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
- char* dir;
- br_init (NULL);
- dir = br_find_data_dir(APPDATADIR);
- datadir = dir;
- free(dir);
-
-#else
- datadir = APPDATADIR;
-#endif
- if(!PHYSFS_addToSearchPath(datadir.c_str(), 1)) {
- log_warning << "Couldn't add '" << datadir << "' to physfs searchpath: " << PHYSFS_getLastError() << std::endl;
- }
-#endif
- }
-
- //show search Path
- char** searchpath = PHYSFS_getSearchPath();
- for(char** i = searchpath; *i != NULL; i++)
- log_info << "[" << *i << "] is in the search path" << std::endl;
- PHYSFS_freeList(searchpath);
-}
-
-static void print_usage(const char* argv0)
-{
- fprintf(stderr, _("Usage: %s [OPTIONS] [LEVELFILE]\n\n"), argv0);
- fprintf(stderr,
- _("Options:\n"
- " -f, --fullscreen Run in fullscreen mode\n"
- " -w, --window Run in window mode\n"
- " -g, --geometry WIDTHxHEIGHT Run SuperTux in given resolution\n"
- " -a, --aspect WIDTH:HEIGHT Run SuperTux with given aspect ratio\n"
- " -d, --default Reset video settings to default values\n"
- " --renderer RENDERER Use sdl, opengl, or auto to render\n"
- " --disable-sfx Disable sound effects\n"
- " --disable-music Disable music\n"
- " -h, --help Show this help message and quit\n"
- " -v, --version Show SuperTux version and quit\n"
- " --console Enable ingame scripting console\n"
- " --noconsole Disable ingame scripting console\n"
- " --show-fps Display framerate in levels\n"
- " --no-show-fps Do not display framerate in levels\n"
- " --record-demo FILE LEVEL Record a demo to FILE\n"
- " --play-demo FILE LEVEL Play a recorded demo\n"
- " -s, --debug-scripts Enable script debugger.\n"
- "%s\n"), "");
-}
-
-/**
- * Options that should be evaluated prior to any initializations at all go here
- */
-static bool pre_parse_commandline(int argc, char** argv)
-{
- for(int i = 1; i < argc; ++i) {
- std::string arg = argv[i];
-
- if(arg == "--version" || arg == "-v") {
- std::cout << PACKAGE_NAME << " " << PACKAGE_VERSION << std::endl;
- return true;
- }
- if(arg == "--help" || arg == "-h") {
- print_usage(argv[0]);
- return true;
- }
- }
-
- return false;
-}
-
-/**
- * Options that should be evaluated after config is read go here
- */
-static bool parse_commandline(int argc, char** argv)
-{
- for(int i = 1; i < argc; ++i) {
- std::string arg = argv[i];
-
- if(arg == "--fullscreen" || arg == "-f") {
- config->use_fullscreen = true;
- } else if(arg == "--default" || arg == "-d") {
- config->use_fullscreen = false;
-
- config->window_width = 800;
- config->window_height = 600;
-
- config->fullscreen_width = 800;
- config->fullscreen_height = 600;
-
- config->aspect_width = 0; // auto detect
- config->aspect_height = 0;
-
- } else if(arg == "--window" || arg == "-w") {
- config->use_fullscreen = false;
- } else if(arg == "--geometry" || arg == "-g") {
- i += 1;
- if(i >= argc)
- {
- print_usage(argv[0]);
- throw std::runtime_error("Need to specify a size (WIDTHxHEIGHT) for geometry argument");
- }
- else
- {
- int width, height;
- if (sscanf(argv[i], "%dx%d", &width, &height) != 2)
- {
- print_usage(argv[0]);
- throw std::runtime_error("Invalid geometry spec, should be WIDTHxHEIGHT");
- }
- else
- {
- config->window_width = width;
- config->window_height = height;
-
- config->fullscreen_width = width;
- config->fullscreen_height = height;
- }
- }
- } else if(arg == "--aspect" || arg == "-a") {
- i += 1;
- if(i >= argc)
- {
- print_usage(argv[0]);
- throw std::runtime_error("Need to specify a ratio (WIDTH:HEIGHT) for aspect ratio");
- }
- else
- {
- int aspect_width = 0;
- int aspect_height = 0;
- if (strcmp(argv[i], "auto") == 0)
- {
- aspect_width = 0;
- aspect_height = 0;
- }
- else if (sscanf(argv[i], "%d:%d", &aspect_width, &aspect_height) != 2)
- {
- print_usage(argv[0]);
- throw std::runtime_error("Invalid aspect spec, should be WIDTH:HEIGHT or auto");
- }
- else
- {
- float aspect_ratio = static_cast<double>(config->aspect_width) /
- static_cast<double>(config->aspect_height);
-
- // use aspect ratio to calculate logical resolution
- if (aspect_ratio > 1) {
- config->aspect_width = static_cast<int> (600 * aspect_ratio + 0.5);
- config->aspect_height = 600;
- } else {
- config->aspect_width = 600;
- config->aspect_height = static_cast<int> (600 * 1/aspect_ratio + 0.5);
- }
- }
- }
- } else if(arg == "--renderer") {
- i += 1;
- if(i >= argc)
- {
- print_usage(argv[0]);
- throw std::runtime_error("Need to specify a renderer for renderer argument");
- }
- else
- {
- config->video = get_video_system(argv[i]);
- }
- } else if(arg == "--show-fps") {
- config->show_fps = true;
- } else if(arg == "--no-show-fps") {
- config->show_fps = false;
- } else if(arg == "--console") {
- config->console_enabled = true;
- } else if(arg == "--noconsole") {
- config->console_enabled = false;
- } else if(arg == "--disable-sfx") {
- config->sound_enabled = false;
- } else if(arg == "--disable-music") {
- config->music_enabled = false;
- } else if(arg == "--play-demo") {
- if(i+1 >= argc) {
- print_usage(argv[0]);
- throw std::runtime_error("Need to specify a demo filename");
- }
- config->start_demo = argv[++i];
- } else if(arg == "--record-demo") {
- if(i+1 >= argc) {
- print_usage(argv[0]);
- throw std::runtime_error("Need to specify a demo filename");
- }
- config->record_demo = argv[++i];
- } else if(arg == "--debug-scripts" || arg == "-s") {
- config->enable_script_debugger = true;
- } else if(arg[0] != '-') {
- config->start_level = arg;
- } else {
- log_warning << "Unknown option '" << arg << "'. Use --help to see a list of options" << std::endl;
- return true;
- }
- }
-
- return false;
-}
-
-static void init_sdl()
-{
- if(SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0) {
- std::stringstream msg;
- msg << "Couldn't initialize SDL: " << SDL_GetError();
- throw std::runtime_error(msg.str());
- }
- // just to be sure
- atexit(SDL_Quit);
-
- SDL_EnableUNICODE(1);
-
- // wait 100ms and clear SDL event queue because sometimes we have random
- // joystick events in the queue on startup...
- SDL_Delay(100);
- SDL_Event dummy;
- while(SDL_PollEvent(&dummy))
- ;
-}
-
-static void init_rand()
-{
- config->random_seed = systemRandom.srand(config->random_seed);
-
- //const char *how = config->random_seed? ", user fixed.": ", from time().";
- //log_info << "Using random seed " << config->random_seed << how << std::endl;
-}
-
-void init_video()
-{
- // FIXME: Add something here
- SCREEN_WIDTH = 800;
- SCREEN_HEIGHT = 600;
-
- context_pointer->init_renderer();
- screen = SDL_GetVideoSurface();
-
- SDL_WM_SetCaption(PACKAGE_NAME " " PACKAGE_VERSION, 0);
-
- // set icon
-#ifdef MACOSX
- const char* icon_fname = "images/engine/icons/supertux-256x256.png";
-#else
- const char* icon_fname = "images/engine/icons/supertux.xpm";
-#endif
- SDL_Surface* icon;
- try {
- icon = IMG_Load_RW(get_physfs_SDLRWops(icon_fname), true);
- } catch (const std::runtime_error& err) {
- icon = 0;
- log_warning << "Couldn't load icon '" << icon_fname << "': " << err.what() << std::endl;
- }
- if(icon != 0) {
- SDL_WM_SetIcon(icon, 0);
- SDL_FreeSurface(icon);
- }
-#ifdef DEBUG
- else {
- log_warning << "Couldn't load icon '" << icon_fname << "'" << std::endl;
- }
-#endif
-
- SDL_ShowCursor(0);
-
- log_info << (config->use_fullscreen?"fullscreen ":"window ")
- << " Window: " << config->window_width << "x" << config->window_height
- << " Fullscreen: " << config->fullscreen_width << "x" << config->fullscreen_height
- << " Area: " << config->aspect_width << "x" << config->aspect_height << std::endl;
-}
-
-static void init_audio()
-{
- sound_manager = new SoundManager();
-
- sound_manager->enable_sound(config->sound_enabled);
- sound_manager->enable_music(config->music_enabled);
-}
-
-static void quit_audio()
-{
- if(sound_manager != NULL) {
- delete sound_manager;
- sound_manager = NULL;
- }
-}
-
-void wait_for_event(float min_delay, float max_delay)
-{
- assert(min_delay <= max_delay);
-
- Uint32 min = (Uint32) (min_delay * 1000);
- Uint32 max = (Uint32) (max_delay * 1000);
-
- Uint32 ticks = SDL_GetTicks();
- while(SDL_GetTicks() - ticks < min) {
- SDL_Delay(10);
- sound_manager->update();
- }
-
- // clear event queue
- SDL_Event event;
- while (SDL_PollEvent(&event))
- {}
-
- /* Handle events: */
- bool running = false;
- ticks = SDL_GetTicks();
- while(running) {
- while(SDL_PollEvent(&event)) {
- switch(event.type) {
- case SDL_QUIT:
- main_loop->quit();
- break;
- case SDL_KEYDOWN:
- case SDL_JOYBUTTONDOWN:
- case SDL_MOUSEBUTTONDOWN:
- running = false;
- }
- }
- if(SDL_GetTicks() - ticks >= (max - min))
- running = false;
- sound_manager->update();
- SDL_Delay(10);
- }
-}
-
-#ifdef DEBUG
-static Uint32 last_timelog_ticks = 0;
-static const char* last_timelog_component = 0;
-
-static inline void timelog(const char* component)
-{
- Uint32 current_ticks = SDL_GetTicks();
-
- if(last_timelog_component != 0) {
- log_info << "Component '" << last_timelog_component << "' finished after " << (current_ticks - last_timelog_ticks) / 1000.0 << " seconds" << std::endl;
- }
-
- last_timelog_ticks = current_ticks;
- last_timelog_component = component;
-}
-#else
-static inline void timelog(const char* )
-{
-}
-#endif
+#include "supertux/main.hpp"
int main(int argc, char** argv)
{
- int result = 0;
-
- try {
-
- if(pre_parse_commandline(argc, argv))
- return 0;
-
- Console::instance = new Console();
- init_physfs(argv[0]);
- init_sdl();
-
- timelog("controller");
- main_controller = new JoystickKeyboardController();
-
- timelog("config");
- init_config();
-
- timelog("addons");
- AddonManager::get_instance().load_addons();
-
- timelog("tinygettext");
- init_tinygettext();
-
- timelog("commandline");
- if(parse_commandline(argc, argv))
- return 0;
-
- timelog("audio");
- init_audio();
-
- timelog("video");
- DrawingContext context;
- context_pointer = &context;
- init_video();
-
- Console::instance->init_graphics();
-
- timelog("scripting");
- Scripting::init_squirrel(config->enable_script_debugger);
-
- timelog("resources");
- load_shared();
-
- timelog(0);
-
- main_loop = new MainLoop();
- if(config->start_level != "") {
- // we have a normal path specified at commandline, not a physfs path.
- // So we simply mount that path here...
- std::string dir = FileSystem::dirname(config->start_level);
- log_debug << "Adding dir: " << dir << std::endl;
- PHYSFS_addToSearchPath(dir.c_str(), true);
-
- if(config->start_level.size() > 4 &&
- config->start_level.compare(config->start_level.size() - 5, 5, ".stwm") == 0) {
- init_rand();
- main_loop->push_screen(new WorldMapNS::WorldMap(
- FileSystem::basename(config->start_level)));
- } else {
- init_rand();//If level uses random eg. for
- // rain particles before we do this:
- std::auto_ptr<GameSession> session (
- new GameSession(FileSystem::basename(config->start_level)));
-
- config->random_seed =session->get_demo_random_seed(config->start_demo);
- init_rand();//initialise generator with seed from session
-
- if(config->start_demo != "")
- session->play_demo(config->start_demo);
-
- if(config->record_demo != "")
- session->record_demo(config->record_demo);
- main_loop->push_screen(session.release());
- }
- } else {
- init_rand();
- main_loop->push_screen(new TitleScreen());
- }
-
- //init_rand(); PAK: this call might subsume the above 3, but I'm chicken!
- main_loop->run(context);
- } catch(std::exception& e) {
- log_fatal << "Unexpected exception: " << e.what() << std::endl;
- result = 1;
- } catch(...) {
- log_fatal << "Unexpected exception" << std::endl;
- result = 1;
- }
-
- delete main_loop;
- main_loop = NULL;
-
- unload_shared();
- quit_audio();
-
- if(config)
- config->save();
- delete config;
- config = NULL;
- delete main_controller;
- main_controller = NULL;
- delete Console::instance;
- Console::instance = NULL;
- Scripting::exit_squirrel();
- delete texture_manager;
- texture_manager = NULL;
- SDL_Quit();
- PHYSFS_deinit();
-
- return result;
+ return supertux_main(argc, argv);
}
+
+/* EOF */
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-#ifndef __MAIN_H__
-#define __MAIN_H__
-
-void init_video();
-void wait_for_event(float min_delay, float max_delay);
-
-/** The width of the display (this is a logical value, not the
- physical value, since aspect_ration and projection_area might
- shrink or scale things) */
-extern int SCREEN_WIDTH;
-
-/** The width of the display (this is a logical value, not the
- physical value, since aspect_ration and projection_area might
- shrink or scale things) */
-extern int SCREEN_HEIGHT;
-
-// global variables
-class JoystickKeyboardController;
-extern JoystickKeyboardController* main_controller;
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include <config.h>
-
-#include "mainloop.hpp"
-
-#include <stdlib.h>
-#include <SDL.h>
-#include "video/drawing_context.hpp"
-#include "control/joystickkeyboardcontroller.hpp"
-#include "gui/menu.hpp"
-#include "audio/sound_manager.hpp"
-#include "scripting/time_scheduler.hpp"
-#include "scripting/squirrel_util.hpp"
-#include "gameconfig.hpp"
-#include "constants.hpp"
-#include "main.hpp"
-#include "resources.hpp"
-#include "screen.hpp"
-#include "screen_fade.hpp"
-#include "timer.hpp"
-#include "player_status.hpp"
-#include "video/renderer.hpp"
-#include "random_generator.hpp"
-
-/** ticks (as returned from SDL_GetTicks) per frame */
-static const Uint32 TICKS_PER_FRAME = (Uint32) (1000.0 / LOGICAL_FPS);
-/** don't skip more than every 2nd frame */
-static const int MAX_FRAME_SKIP = 2;
-
-float game_speed = 1.0f;
-
-MainLoop* main_loop = NULL;
-
-MainLoop::MainLoop()
- : speed(1.0), nextpop(false), nextpush(false), fps(0), screenshot_requested(false)
-{
- using namespace Scripting;
- TimeScheduler::instance = new TimeScheduler();
-}
-
-MainLoop::~MainLoop()
-{
- using namespace Scripting;
- delete TimeScheduler::instance;
- TimeScheduler::instance = NULL;
-
- for(std::vector<Screen*>::iterator i = screen_stack.begin();
- i != screen_stack.end(); ++i) {
- delete *i;
- }
-}
-
-void
-MainLoop::push_screen(Screen* screen, ScreenFade* screen_fade)
-{
- this->next_screen.reset(screen);
- this->screen_fade.reset(screen_fade);
- nextpush = !nextpop;
- nextpop = false;
- speed = 1.0f;
-}
-
-void
-MainLoop::exit_screen(ScreenFade* screen_fade)
-{
- next_screen.reset(NULL);
- this->screen_fade.reset(screen_fade);
- nextpop = true;
- nextpush = false;
-}
-
-void
-MainLoop::set_screen_fade(ScreenFade* screen_fade)
-{
- this->screen_fade.reset(screen_fade);
-}
-
-void
-MainLoop::quit(ScreenFade* screen_fade)
-{
- for(std::vector<Screen*>::iterator i = screen_stack.begin();
- i != screen_stack.end(); ++i)
- delete *i;
- screen_stack.clear();
-
- exit_screen(screen_fade);
-}
-
-void
-MainLoop::set_speed(float speed)
-{
- this->speed = speed;
-}
-
-float
-MainLoop::get_speed() const
-{
- return speed;
-}
-
-bool
-MainLoop::has_no_pending_fadeout() const
-{
- return screen_fade.get() == NULL || screen_fade->done();
-}
-
-void
-MainLoop::draw_fps(DrawingContext& context, float fps_fps)
-{
- char str[60];
- snprintf(str, sizeof(str), "%3.1f", fps_fps);
- const char* fpstext = "FPS";
- context.draw_text(small_font, fpstext, Vector(SCREEN_WIDTH - small_font->get_text_width(fpstext) - small_font->get_text_width(" 99999") - BORDER_X, BORDER_Y + 20), ALIGN_LEFT, LAYER_HUD);
- context.draw_text(small_font, str, Vector(SCREEN_WIDTH - BORDER_X, BORDER_Y + 20), ALIGN_RIGHT, LAYER_HUD);
-}
-
-void
-MainLoop::draw(DrawingContext& context)
-{
- static Uint32 fps_ticks = SDL_GetTicks();
- static int frame_count = 0;
-
- current_screen->draw(context);
- if(Menu::current() != NULL)
- Menu::current()->draw(context);
- if(screen_fade.get() != NULL)
- screen_fade->draw(context);
- Console::instance->draw(context);
-
- if(config->show_fps)
- draw_fps(context, fps);
-
- // if a screenshot was requested, pass request on to drawing_context
- if (screenshot_requested) {
- context.take_screenshot();
- screenshot_requested = false;
- }
- context.do_drawing();
-
- /* Calculate frames per second */
- if(config->show_fps)
- {
- ++frame_count;
-
- if(SDL_GetTicks() - fps_ticks >= 500)
- {
- fps = (float) frame_count / .5;
- frame_count = 0;
- fps_ticks = SDL_GetTicks();
- }
- }
-}
-
-void
-MainLoop::update_gamelogic(float elapsed_time)
-{
- Scripting::update_debugger();
- Scripting::TimeScheduler::instance->update(game_time);
- current_screen->update(elapsed_time);
- if (Menu::current() != NULL)
- Menu::current()->update();
- if(screen_fade.get() != NULL)
- screen_fade->update(elapsed_time);
- Console::instance->update(elapsed_time);
-}
-
-void
-MainLoop::process_events()
-{
- main_controller->update();
- Uint8* keystate = SDL_GetKeyState(NULL);
- SDL_Event event;
- while(SDL_PollEvent(&event))
- {
- main_controller->process_event(event);
-
- if(Menu::current() != NULL)
- Menu::current()->event(event);
-
- switch(event.type)
- {
- case SDL_QUIT:
- quit();
- break;
-
- case SDL_VIDEORESIZE:
- Renderer::instance()->resize(event.resize.w, event.resize.h);
- Menu::recalc_pos();
- break;
-
- case SDL_KEYDOWN:
- if (event.key.keysym.sym == SDLK_F10)
- {
- config->show_fps = !config->show_fps;
- }
- if (event.key.keysym.sym == SDLK_F11)
- {
- config->use_fullscreen = !config->use_fullscreen;
- init_video();
- Menu::recalc_pos();
- }
- else if (event.key.keysym.sym == SDLK_PRINT ||
- event.key.keysym.sym == SDLK_F12)
- {
- take_screenshot();
- }
- else if (event.key.keysym.sym == SDLK_F1 &&
- (keystate[SDLK_LCTRL] || keystate[SDLK_RCTRL]) &&
- keystate[SDLK_c])
- {
- Console::instance->toggle();
- config->console_enabled = true;
- config->save();
- }
- break;
- }
- }
-}
-
-void
-MainLoop::handle_screen_switch()
-{
- while( (next_screen.get() != NULL || nextpop) &&
- has_no_pending_fadeout()) {
- if(current_screen.get() != NULL) {
- current_screen->leave();
- }
-
- if(nextpop) {
- if(screen_stack.empty()) {
- running = false;
- break;
- }
- next_screen.reset(screen_stack.back());
- screen_stack.pop_back();
- }
- if(nextpush && current_screen.get() != NULL) {
- screen_stack.push_back(current_screen.release());
- }
-
- nextpush = false;
- nextpop = false;
- speed = 1.0;
- Screen* next_screen_ptr = next_screen.release();
- next_screen.reset(0);
- if(next_screen_ptr)
- next_screen_ptr->setup();
- current_screen.reset(next_screen_ptr);
- screen_fade.reset(NULL);
-
- waiting_threads.wakeup();
- }
-}
-
-void
-MainLoop::run(DrawingContext &context)
-{
- Uint32 last_ticks = 0;
- Uint32 elapsed_ticks = 0;
-
- running = true;
- while(running) {
-
- handle_screen_switch();
- if(!running || current_screen.get() == NULL)
- break;
-
- Uint32 ticks = SDL_GetTicks();
- elapsed_ticks += ticks - last_ticks;
- last_ticks = ticks;
-
- Uint32 ticks_per_frame = (Uint32) (TICKS_PER_FRAME * game_speed);
-
- if (elapsed_ticks > ticks_per_frame*4) {
- // when the game loads up or levels are switched the
- // elapsed_ticks grows extremely large, so we just ignore those
- // large time jumps
- elapsed_ticks = 0;
- }
-
- if(elapsed_ticks < ticks_per_frame)
- {
- Uint32 delay_ticks = ticks_per_frame - elapsed_ticks;
- SDL_Delay(delay_ticks);
- last_ticks += delay_ticks;
- elapsed_ticks += delay_ticks;
- }
-
- int frames = 0;
-
- while(elapsed_ticks >= ticks_per_frame && frames < MAX_FRAME_SKIP)
- {
- elapsed_ticks -= ticks_per_frame;
- float timestep = 1.0 / LOGICAL_FPS;
- real_time += timestep;
- timestep *= speed;
- game_time += timestep;
-
- process_events();
- update_gamelogic(timestep);
- frames += 1;
- }
-
- draw(context);
-
- sound_manager->update();
- }
-}
-
-void
-MainLoop::take_screenshot()
-{
- screenshot_requested = true;
-}
-
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#ifndef __MAINLOOP_HPP__
-#define __MAINLOOP_HPP__
-
-#include <memory>
-#include <vector>
-#include "scripting/thread_queue.hpp"
-
-class Screen;
-class Console;
-class ScreenFade;
-class DrawingContext;
-
-/**
- * Manages, updates and draws all Screens, Controllers, Menus and the Console.
- */
-class MainLoop
-{
-public:
- MainLoop();
- ~MainLoop();
-
- void run(DrawingContext &context);
- void exit_screen(ScreenFade* fade = NULL);
- void quit(ScreenFade* fade = NULL);
- void set_speed(float speed);
- float get_speed() const;
- bool has_no_pending_fadeout() const;
-
- /**
- * requests that a screenshot be taken after the next frame has been rendered
- */
- void take_screenshot();
-
- // push new screen on screen_stack
- void push_screen(Screen* screen, ScreenFade* fade = NULL);
- void set_screen_fade(ScreenFade* fade);
-
- /// threads that wait for a screenswitch
- Scripting::ThreadQueue waiting_threads;
-
-private:
- void draw_fps(DrawingContext& context, float fps);
- void draw(DrawingContext& context);
- void update_gamelogic(float elapsed_time);
- void process_events();
- void handle_screen_switch();
-
- bool running;
- float speed;
- bool nextpop;
- bool nextpush;
- /// measured fps
- float fps;
- std::auto_ptr<Screen> next_screen;
- std::auto_ptr<Screen> current_screen;
- std::auto_ptr<Console> console;
- std::auto_ptr<ScreenFade> screen_fade;
- std::vector<Screen*> screen_stack;
- bool screenshot_requested; /**< true if a screenshot should be taken after the next frame has been rendered */
-};
-
-extern MainLoop* main_loop;
-
-#endif
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __AATRIANGLE_H__
-#define __AATRIANGLE_H__
+#ifndef HEADER_SUPERTUX_MATH_AATRIANGLE_HPP
+#define HEADER_SUPERTUX_MATH_AATRIANGLE_HPP
-#include "rect.hpp"
+#include "math/rect.hpp"
/**
* An axis-aligned triangle (ie. a triangle where 2 sides are parallel to the x-
};
#endif
+
+/* EOF */
--- /dev/null
+// $Id$
+//
+// A strong random number generator
+//
+// Copyright (C) 2006 Allen King
+// Copyright (C) 2002 Michael Ringgaard. All rights reserved.
+// Copyright (C) 1983, 1993 The Regents of the University of California.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the project nor the names of its contributors
+// may be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+// SUCH DAMAGE.
+
+// Transliterated into C++ Allen King 060417, from sources on
+// http://www.jbox.dk/sanos/source/lib/random.c.html
+
+#include <cassert>
+#include <stdexcept>
+#include <stdio.h>
+#include <time.h>
+
+#include "math/random_generator.hpp"
+
+RandomGenerator systemRandom; // global random number generator
+
+RandomGenerator::RandomGenerator() {
+ assert(sizeof(int) >= 4);
+ initialized = 0;
+ debug = 0; // change this by hand for debug
+ initialize();
+}
+
+RandomGenerator::~RandomGenerator() {
+}
+
+int RandomGenerator::srand(int x) {
+ int x0 = x;
+ while (x <= 0) // random seed of zero means
+ x = time(0) % RandomGenerator::rand_max; // randomize with time
+
+ if (debug > 0)
+ printf("==== srand(%10d) (%10d) rand_max=%x =====\n",
+ x, x0, RandomGenerator::rand_max);
+
+ RandomGenerator::srandom(x);
+ return x; // let caller know seed used
+}
+
+int RandomGenerator::rand() {
+ int rv; // a positive int
+ while ((rv = RandomGenerator::random()) <= 0) // neg or zero causes probs
+ ;
+ if (debug > 0)
+ printf("==== rand(): %10d =====\n", rv);
+ return rv;
+}
+
+int RandomGenerator::rand(int v) {
+ assert(v >= 0 && v <= RandomGenerator::rand_max); // illegal arg
+
+ // remove biases, esp. when v is large (e.g. v == (rand_max/4)*3;)
+ int rv, maxV =(RandomGenerator::rand_max / v) * v;
+ assert(maxV <= RandomGenerator::rand_max);
+ while ((rv = RandomGenerator::random()) >= maxV)
+ ;
+ return rv % v; // mod it down to 0..(maxV-1)
+}
+
+int RandomGenerator::rand(int u, int v) {
+ assert(v > u);
+ return u + RandomGenerator::rand(v-u);
+}
+
+double RandomGenerator::randf(double v) {
+ float rv;
+ do {
+ rv = ((double)RandomGenerator::random())/RandomGenerator::rand_max * v;
+ } while (rv >= v); // rounding might cause rv==v
+
+ if (debug > 0)
+ printf("==== rand(): %f =====\n", rv);
+ return rv;
+}
+
+double RandomGenerator::randf(double u, double v) {
+ return u + RandomGenerator::randf(v-u);
+}
+
+//-----------------------------------------------------------------------
+//
+// Copyright (C) 2002 Michael Ringgaard. All rights reserved.
+// Copyright (C) 1983, 1993 The Regents of the University of California.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the project nor the names of its contributors
+// may be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+// SUCH DAMAGE.
+//
+
+//**#include <os.h>
+
+//
+// An improved random number generation package. In addition to the standard
+// rand()/srand() like interface, this package also has a special state info
+// interface. The initstate() routine is called with a seed, an array of
+// bytes, and a count of how many bytes are being passed in; this array is
+// then initialized to contain information for random number generation with
+// that much state information. Good sizes for the amount of state
+// information are 32, 64, 128, and 256 bytes. The state can be switched by
+// calling the setstate() routine with the same array as was initialized
+// with initstate(). By default, the package runs with 128 bytes of state
+// information and generates far better random numbers than a linear
+// congruential generator. If the amount of state information is less than
+// 32 bytes, a simple linear congruential R.N.G. is used.
+//
+// Internally, the state information is treated as an array of longs; the
+// zeroeth element of the array is the type of R.N.G. being used (small
+// integer); the remainder of the array is the state information for the
+// R.N.G. Thus, 32 bytes of state information will give 7 longs worth of
+// state information, which will allow a degree seven polynomial. (Note:
+// the zeroeth word of state information also has some other information
+// stored in it -- see setstate() for details).
+//
+// The random number generation technique is a linear feedback shift register
+// approach, employing trinomials (since there are fewer terms to sum up that
+// way). In this approach, the least significant bit of all the numbers in
+// the state table will act as a linear feedback shift register, and will
+// have period 2^deg - 1 (where deg is the degree of the polynomial being
+// used, assuming that the polynomial is irreducible and primitive). The
+// higher order bits will have longer periods, since their values are also
+// influenced by pseudo-random carries out of the lower bits. The total
+// period of the generator is approximately deg*(2**deg - 1); thus doubling
+// the amount of state information has a vast influence on the period of the
+// generator. Note: the deg*(2**deg - 1) is an approximation only good for
+// large deg, when the period of the shift is the dominant factor.
+// With deg equal to seven, the period is actually much longer than the
+// 7*(2**7 - 1) predicted by this formula.
+//
+// Modified 28 December 1994 by Jacob S. Rosenberg.
+//
+
+//
+// For each of the currently supported random number generators, we have a
+// break value on the amount of state information (you need at least this
+// many bytes of state info to support this random number generator), a degree
+// for the polynomial (actually a trinomial) that the R.N.G. is based on, and
+// the separation between the two lower order coefficients of the trinomial.
+
+void RandomGenerator::initialize() {
+
+#define NSHUFF 100 // To drop part of seed -> 1st value correlation
+
+ //static long degrees[MAX_TYPES] = { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 };
+ //static long seps [MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 };
+
+ degrees[0] = DEG_0;
+ degrees[1] = DEG_1;
+ degrees[2] = DEG_2;
+ degrees[3] = DEG_3;
+ degrees[4] = DEG_4;
+
+ seps [0] = SEP_0;
+ seps [1] = SEP_1;
+ seps [2] = SEP_2;
+ seps [3] = SEP_3;
+ seps [4] = SEP_4;
+
+ //
+ // Initially, everything is set up as if from:
+ //
+ // initstate(1, randtbl, 128);
+ //
+ // Note that this initialization takes advantage of the fact that srandom()
+ // advances the front and rear pointers 10*rand_deg times, and hence the
+ // rear pointer which starts at 0 will also end up at zero; thus the zeroeth
+ // element of the state information, which contains info about the current
+ // position of the rear pointer is just
+ //
+ // MAX_TYPES * (rptr - state) + TYPE_3 == TYPE_3.
+
+ randtbl[ 0] = TYPE_3;
+ randtbl[ 1] = 0x991539b1;
+ randtbl[ 2] = 0x16a5bce3;
+ randtbl[ 3] = 0x6774a4cd;
+ randtbl[ 4] = 0x3e01511e;
+ randtbl[ 5] = 0x4e508aaa;
+ randtbl[ 6] = 0x61048c05;
+ randtbl[ 7] = 0xf5500617;
+ randtbl[ 8] = 0x846b7115;
+ randtbl[ 9] = 0x6a19892c;
+ randtbl[10] = 0x896a97af;
+ randtbl[11] = 0xdb48f936;
+ randtbl[12] = 0x14898454;
+ randtbl[13] = 0x37ffd106;
+ randtbl[14] = 0xb58bff9c;
+ randtbl[15] = 0x59e17104;
+ randtbl[16] = 0xcf918a49;
+ randtbl[17] = 0x09378c83;
+ randtbl[18] = 0x52c7a471;
+ randtbl[19] = 0x8d293ea9;
+ randtbl[20] = 0x1f4fc301;
+ randtbl[21] = 0xc3db71be;
+ randtbl[22] = 0x39b44e1c;
+ randtbl[23] = 0xf8a44ef9;
+ randtbl[24] = 0x4c8b80b1;
+ randtbl[25] = 0x19edc328;
+ randtbl[26] = 0x87bf4bdd;
+ randtbl[27] = 0xc9b240e5;
+ randtbl[28] = 0xe9ee4b1b;
+ randtbl[29] = 0x4382aee7;
+ randtbl[30] = 0x535b6b41;
+ randtbl[31] = 0xf3bec5da;
+
+ // static long randtbl[DEG_3 + 1] =
+ // {
+ // TYPE_3;
+ // 0x991539b1, 0x16a5bce3, 0x6774a4cd, 0x3e01511e, 0x4e508aaa, 0x61048c05,
+ // 0xf5500617, 0x846b7115, 0x6a19892c, 0x896a97af, 0xdb48f936, 0x14898454,
+ // 0x37ffd106, 0xb58bff9c, 0x59e17104, 0xcf918a49, 0x09378c83, 0x52c7a471,
+ // 0x8d293ea9, 0x1f4fc301, 0xc3db71be, 0x39b44e1c, 0xf8a44ef9, 0x4c8b80b1,
+ // 0x19edc328, 0x87bf4bdd, 0xc9b240e5, 0xe9ee4b1b, 0x4382aee7, 0x535b6b41,
+ // 0xf3bec5da
+ // };
+
+ //
+ // fptr and rptr are two pointers into the state info, a front and a rear
+ // pointer. These two pointers are always rand_sep places aparts, as they
+ // cycle cyclically through the state information. (Yes, this does mean we
+ // could get away with just one pointer, but the code for random() is more
+ // efficient this way). The pointers are left positioned as they would be
+ // from the call
+ //
+ // initstate(1, randtbl, 128);
+ //
+ // (The position of the rear pointer, rptr, is really 0 (as explained above
+ // in the initialization of randtbl) because the state table pointer is set
+ // to point to randtbl[1] (as explained below).
+ //
+
+ fptr = &randtbl[SEP_3 + 1];
+ rptr = &randtbl[1];
+
+ //
+ // The following things are the pointer to the state information table, the
+ // type of the current generator, the degree of the current polynomial being
+ // used, and the separation between the two pointers. Note that for efficiency
+ // of random(), we remember the first location of the state information, not
+ // the zeroeth. Hence it is valid to access state[-1], which is used to
+ // store the type of the R.N.G. Also, we remember the last location, since
+ // this is more efficient than indexing every time to find the address of
+ // the last element to see if the front and rear pointers have wrapped.
+ //
+
+ state = &randtbl[1];
+ rand_type = TYPE_3;
+ rand_deg = DEG_3;
+ rand_sep = SEP_3;
+ end_ptr = &randtbl[DEG_3 + 1];
+
+}
+
+//
+// Compute x = (7^5 * x) mod (2^31 - 1)
+// without overflowing 31 bits:
+// (2^31 - 1) = 127773 * (7^5) + 2836
+// From "Random number generators: good ones are hard to find",
+// Park and Miller, Communications of the ACM, vol. 31, no. 10,
+// October 1988, p. 1195.
+//
+
+__inline static long good_rand(long x)
+{
+ long hi, lo;
+
+ // Can't be initialized with 0, so use another value.
+ if (x == 0) x = 123459876;
+ hi = x / 127773;
+ lo = x % 127773;
+ x = 16807 * lo - 2836 * hi;
+ if (x < 0) x += 0x7fffffff;
+ return x;
+}
+
+//
+// srandom
+//
+// Initialize the random number generator based on the given seed. If the
+// type is the trivial no-state-information type, just remember the seed.
+// Otherwise, initializes state[] based on the given "seed" via a linear
+// congruential generator. Then, the pointers are set to known locations
+// that are exactly rand_sep places apart. Lastly, it cycles the state
+// information a given number of times to get rid of any initial dependencies
+// introduced by the L.C.R.N.G. Note that the initialization of randtbl[]
+// for default usage relies on values produced by this routine.
+
+void RandomGenerator::srandom(unsigned long x)
+{
+ long i, lim;
+
+ state[0] = x;
+ if (rand_type == TYPE_0)
+ lim = NSHUFF;
+ else
+ {
+ for (i = 1; i < rand_deg; i++) state[i] = good_rand(state[i - 1]);
+ fptr = &state[rand_sep];
+ rptr = &state[0];
+ lim = 10 * rand_deg;
+ }
+
+ initialized = 1;
+ for (i = 0; i < lim; i++) random();
+}
+
+#ifdef NOT_FOR_SUPERTUX // use in supertux doesn't require these methods,
+// which are not portable to as many platforms as
+// SDL. The cost is that the variability of the
+// initial seed is reduced to only 32 bits of
+// randomness, seemingly enough. PAK 060420
+//
+// srandomdev
+//
+// Many programs choose the seed value in a totally predictable manner.
+// This often causes problems. We seed the generator using the much more
+// secure random() interface. Note that this particular seeding
+// procedure can generate states which are impossible to reproduce by
+// calling srandom() with any value, since the succeeding terms in the
+// state buffer are no longer derived from the LC algorithm applied to
+// a fixed seed.
+
+void RandomGenerator::srandomdev()
+{
+ int fd, done;
+ size_t len;
+
+ if (rand_type == TYPE_0)
+ len = sizeof state[0];
+ else
+ len = rand_deg * sizeof state[0];
+
+ done = 0;
+ fd = open("/dev/urandom", O_RDONLY);
+ if (fd >= 0)
+ {
+ if (read(fd, state, len) == len) done = 1;
+ close(fd);
+ }
+
+ if (!done)
+ {
+ struct timeval tv;
+
+ gettimeofday(&tv, NULL);
+ srandom(tv.tv_sec ^ tv.tv_usec);
+ return;
+ }
+
+ if (rand_type != TYPE_0)
+ {
+ fptr = &state[rand_sep];
+ rptr = &state[0];
+ }
+ initialized = 1;
+}
+
+//
+// initstate
+//
+// Initialize the state information in the given array of n bytes for future
+// random number generation. Based on the number of bytes we are given, and
+// the break values for the different R.N.G.'s, we choose the best (largest)
+// one we can and set things up for it. srandom() is then called to
+// initialize the state information.
+//
+// Note that on return from srandom(), we set state[-1] to be the type
+// multiplexed with the current value of the rear pointer; this is so
+// successive calls to initstate() won't lose this information and will be
+// able to restart with setstate().
+//
+// Note: the first thing we do is save the current state, if any, just like
+// setstate() so that it doesn't matter when initstate is called.
+//
+// Returns a pointer to the old state.
+//
+
+char * RandomGenerator::initstate(unsigned long seed, char *arg_state, long n)
+{
+ char *ostate = (char *) (&state[-1]);
+ long *long_arg_state = (long *) arg_state;
+
+ if (rand_type == TYPE_0)
+ state[-1] = rand_type;
+ else
+ state[-1] = MAX_TYPES * (rptr - state) + rand_type;
+
+ if (n < BREAK_0) return NULL;
+
+ if (n < BREAK_1)
+ {
+ rand_type = TYPE_0;
+ rand_deg = DEG_0;
+ rand_sep = SEP_0;
+ }
+ else if (n < BREAK_2)
+ {
+ rand_type = TYPE_1;
+ rand_deg = DEG_1;
+ rand_sep = SEP_1;
+ }
+ else if (n < BREAK_3)
+ {
+ rand_type = TYPE_2;
+ rand_deg = DEG_2;
+ rand_sep = SEP_2;
+ }
+ else if (n < BREAK_4)
+ {
+ rand_type = TYPE_3;
+ rand_deg = DEG_3;
+ rand_sep = SEP_3;
+ }
+ else
+ {
+ rand_type = TYPE_4;
+ rand_deg = DEG_4;
+ rand_sep = SEP_4;
+ }
+
+ state = (long *) (long_arg_state + 1); // First location
+ end_ptr = &state[rand_deg]; // Must set end_ptr before srandom
+ srandom(seed);
+
+ if (rand_type == TYPE_0)
+ long_arg_state[0] = rand_type;
+ else
+ long_arg_state[0] = MAX_TYPES * (rptr - state) + rand_type;
+
+ initialized = 1;
+ return ostate;
+}
+
+//
+// setstate
+//
+// Restore the state from the given state array.
+//
+// Note: it is important that we also remember the locations of the pointers
+// in the current state information, and restore the locations of the pointers
+// from the old state information. This is done by multiplexing the pointer
+// location into the zeroeth word of the state information.
+//
+// Note that due to the order in which things are done, it is OK to call
+// setstate() with the same state as the current state.
+//
+// Returns a pointer to the old state information.
+//
+
+char * RandomGenerator::setstate(char *arg_state)
+{
+ long *new_state = (long *) arg_state;
+ long type = new_state[0] % MAX_TYPES;
+ long rear = new_state[0] / MAX_TYPES;
+ char *ostate = (char *) (&state[-1]);
+
+ if (rand_type == TYPE_0)
+ state[-1] = rand_type;
+ else
+ state[-1] = MAX_TYPES * (rptr - state) + rand_type;
+
+ switch(type)
+ {
+ case TYPE_0:
+ case TYPE_1:
+ case TYPE_2:
+ case TYPE_3:
+ case TYPE_4:
+ rand_type = type;
+ rand_deg = degrees[type];
+ rand_sep = seps[type];
+ break;
+ }
+
+ state = (long *) (new_state + 1);
+ if (rand_type != TYPE_0)
+ {
+ rptr = &state[rear];
+ fptr = &state[(rear + rand_sep) % rand_deg];
+ }
+ end_ptr = &state[rand_deg]; // Set end_ptr too
+
+ initialized = 1;
+ return ostate;
+}
+#endif //NOT_FOR_SUPERTUX
+//
+// random:
+//
+// If we are using the trivial TYPE_0 R.N.G., just do the old linear
+// congruential bit. Otherwise, we do our fancy trinomial stuff, which is
+// the same in all the other cases due to all the global variables that have
+// been set up. The basic operation is to add the number at the rear pointer
+// into the one at the front pointer. Then both pointers are advanced to
+// the next location cyclically in the table. The value returned is the sum
+// generated, reduced to 31 bits by throwing away the "least random" low bit.
+//
+// Note: the code takes advantage of the fact that both the front and
+// rear pointers can't wrap on the same call by not testing the rear
+// pointer if the front one has wrapped.
+//
+// Returns a 31-bit random number.
+//
+
+long RandomGenerator::random()
+{
+ long i;
+ long *f, *r;
+ if (!initialized) {
+ throw std::runtime_error("uninitialized RandomGenerator object");
+ }
+
+ if (rand_type == TYPE_0)
+ {
+ i = state[0];
+ state[0] = i = (good_rand(i)) & 0x7fffffff;
+ }
+ else
+ {
+ f = fptr; r = rptr;
+ *f += *r;
+ i = (*f >> 1) & 0x7fffffff; // Chucking least random bit
+ if (++f >= end_ptr)
+ {
+ f = state;
+ ++r;
+ }
+ else if (++r >= end_ptr)
+ r = state;
+
+ fptr = f; rptr = r;
+ }
+
+ return i;
+}
+
+/* EOF */
--- /dev/null
+// $Id$
+//
+// A strong random number generator
+//
+// Copyright (C) 2006 Allen King
+// Copyright (C) 2002 Michael Ringgaard. All rights reserved.
+// Copyright (C) 1983, 1993 The Regents of the University of California.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the project nor the names of its contributors
+// may be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+// SUCH DAMAGE.
+
+#ifndef HEADER_SUPERTUX_MATH_RANDOM_GENERATOR_HPP
+#define HEADER_SUPERTUX_MATH_RANDOM_GENERATOR_HPP
+
+class RandomGenerator
+{
+private:
+ // Array versions of the above information to make code run faster --
+ // relies on fact that TYPE_i == i.
+ static const int TYPE_0 = 0; // Linear congruential
+ static const int BREAK_0 = 8;
+ static const int DEG_0 = 0;
+ static const int SEP_0 = 0;
+
+ static const int TYPE_1 = 1; // x**7 + x**3 + 1
+ static const int BREAK_1 = 32;
+ static const int DEG_1 = 7;
+ static const int SEP_1 = 3;
+
+ static const int TYPE_2 = 2; // x**15 + x + 1
+ static const int BREAK_2 = 64;
+ static const int DEG_2 = 15;
+ static const int SEP_2 = 1;
+
+ static const int TYPE_3 = 3; // x**31 + x**3 + 1
+ static const int BREAK_3 = 128;
+ static const int DEG_3 = 31;
+ static const int SEP_3 = 3;
+
+ static const int TYPE_4 = 4; // x**63 + x + 1
+ static const int BREAK_4 = 256;
+ static const int DEG_4 = 63;
+ static const int SEP_4 = 1;
+
+ static const int MAX_TYPES = 5; // Max number of types above
+
+ bool initialized;
+ long degrees[MAX_TYPES];
+ long seps [MAX_TYPES];
+ long randtbl[DEG_3 + 1];
+
+ long *fptr;
+ long *rptr;
+
+ long *state;
+ long rand_type;
+ long rand_deg;
+ long rand_sep;
+ long *end_ptr;
+ int debug;
+ static const int rand_max = 0x7fffffff; // biggest signed Uint32
+
+public:
+ RandomGenerator();
+ ~RandomGenerator();
+
+ // Documentation of user-visible calls:
+
+ // Initialize the RNG with a 31-bit seed
+ // if x is zero or absent, calls to time() will get a time-randomized seed
+ // the value returned is the value of the seed used.
+ int srand(int x=0);
+
+ // generate random 31-bit numbers
+ // calls to the following return a value evenly distributed between u (or
+ // 0 if not specified) and v (or rand_max if not specified). Return
+ // values may include u, but never v.
+ int rand();
+ int rand(int v);
+ int rand(int u, int v);
+ double randf(double v);
+ double randf(double u, double v);
+
+ // For Squirrel wrapper, since miniswig (and even squirrel?) doesn't
+ // support function overloading or doubles
+ int rand1i(int v) { return rand(v); }
+ int rand2i(int u, int v) { return rand(u, v); }
+ float rand1f(float v)
+ { return static_cast<float>(randf(static_cast<double>(v))); }
+ float rand2f(float u, float v)
+ { return static_cast<float>(randf(static_cast<double>(u),
+ static_cast<double>(v))); }
+
+ //private:
+ void initialize();
+ void srandom(unsigned long x);
+ // void srandomdev();
+ // char *initstate(unsigned long seed, char *arg_state, long n);
+ // char *setstate(char *arg_state);
+ long random();
+
+private:
+ RandomGenerator(const RandomGenerator&);
+ RandomGenerator& operator=(const RandomGenerator&);
+};
+
+extern RandomGenerator systemRandom;
+
+#endif //__RANDOM_GENERATOR__
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __RECT_H__
-#define __RECT_H__
+#ifndef HEADER_SUPERTUX_MATH_RECT_HPP
+#define HEADER_SUPERTUX_MATH_RECT_HPP
#include <assert.h>
-#include "vector.hpp"
+
+#include "math/vector.hpp"
/** This class represents a rectangle.
* (Implementation Note) We're using upper left and lower right point instead of
class Rect
{
public:
- Rect()
+ Rect() :
+ p1(),
+ p2()
{ }
Rect(const Vector& np1, const Vector& np2)
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <cmath>
{
return sqrt(x*x + y*y);
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef SUPERTUX_VECTOR_H
-#define SUPERTUX_VECTOR_H
+#ifndef HEADER_SUPERTUX_MATH_VECTOR_HPP
+#define HEADER_SUPERTUX_MATH_VECTOR_HPP
/** Simple two dimensional vector. */
class Vector
{
public:
Vector(float nx, float ny)
- : x(nx), y(ny)
+ : x(nx), y(ny)
{ }
Vector(const Vector& other)
- : x(other.x), y(other.y)
+ : x(other.x), y(other.y)
{ }
Vector()
- : x(0), y(0)
+ : x(0), y(0)
{ }
bool operator ==(const Vector& other) const
- {
- return x == other.x && y == other.y;
- }
+ {
+ return x == other.x && y == other.y;
+ }
bool operator !=(const Vector& other) const
- {
- return !(x == other.x && y == other.y);
- }
+ {
+ return !(x == other.x && y == other.y);
+ }
const Vector& operator=(const Vector& other)
{
}
Vector operator+(const Vector& other) const
- {
- return Vector(x + other.x, y + other.y);
- }
+ {
+ return Vector(x + other.x, y + other.y);
+ }
Vector operator-(const Vector& other) const
- {
- return Vector(x - other.x, y - other.y);
- }
+ {
+ return Vector(x - other.x, y - other.y);
+ }
Vector operator*(float s) const
- {
- return Vector(x * s, y * s);
- }
+ {
+ return Vector(x * s, y * s);
+ }
Vector operator/(float s) const
- {
- return Vector(x / s, y / s);
- }
+ {
+ return Vector(x / s, y / s);
+ }
Vector operator-() const
- {
- return Vector(-x, -y);
- }
+ {
+ return Vector(-x, -y);
+ }
const Vector& operator +=(const Vector& other)
{
/// Scalar product of 2 vectors
float operator*(const Vector& other) const
- {
- return x*other.x + y*other.y;
- }
+ {
+ return x*other.x + y*other.y;
+ }
float norm() const;
Vector unit() const;
};
#endif
+
+/* EOF */
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include <config.h>
-
-#include "moving_object.hpp"
-
-MovingObject::MovingObject()
-{
- group = COLGROUP_MOVING;
-}
-
-MovingObject::~MovingObject()
-{
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#ifndef SUPERTUX_MOVING_OBJECT_H
-#define SUPERTUX_MOVING_OBJECT_H
-
-#include <stdint.h>
-
-#include "game_object.hpp"
-#include "collision_hit.hpp"
-#include "math/vector.hpp"
-#include "math/rect.hpp"
-
-class Sector;
-class CollisionGrid;
-
-enum CollisionGroup {
- /** Objects in DISABLED group are not tested for collisions */
- COLGROUP_DISABLED = 0,
- /**
- * "default" is moving object. MovingObjects get tested against all other
- * objects and against other movingobjects
- */
- COLGROUP_MOVING,
- /**
- * a Moving object, that is not tested against other MovingObjects (or other
- * MovingOnlyStatic objects), but is tested against all other objects.
- */
- COLGROUP_MOVING_ONLY_STATIC,
- /** TODO write docu :-/ */
- COLGROUP_MOVING_STATIC,
- /**
- * Doesn't move and isn't explicitly checked for collisions with other
- * objects (but other objects might check with this)
- * The difference to COLGROUP_TOUCHABLE is that we can do multiple
- * collision response tests in a row which is needed for static object
- * that tux walks on. The results for collisions with STATIC objects
- * are also sorted by time (so that the first hit gets handled first).
- *
- * Use this for static obstacles
- */
- COLGROUP_STATIC,
- /**
- * Isn't explicitly checked for collisions with other objects. But other
- * objects might check with this object.
- * Difference to COLGROUP_STATIC is that collisions with this object are
- * only tested once and collision response is typically not handled
- *
- * Use this for touchable things like spikes/areas or collectibles like
- * coins
- */
- COLGROUP_TOUCHABLE,
-
- /**
- * Should be used for tilemaps
- */
- COLGROUP_TILEMAP
-};
-
-/**
- * Base class for all dynamic/moving game objects. This class contains things
- * for handling the bounding boxes and collision feedback.
- */
-class MovingObject : public GameObject
-{
-public:
- MovingObject();
- virtual ~MovingObject();
-
- /** this function is called when the object collided with something solid */
- virtual void collision_solid(const CollisionHit& hit)
- {
- (void) hit;
- }
- /**
- * when 2 objects collided, we will first call the pre_collision_check
- * functions of both objects that can decide on how to react to the collision.
- */
- virtual bool collides(GameObject& other, const CollisionHit& hit)
- {
- (void) other;
- (void) hit;
- return true;
- }
- /** this function is called when the object collided with any other object */
- virtual HitResponse collision(GameObject& other, const CollisionHit& hit) = 0;
- /** called when tiles with special attributes have been touched */
- virtual void collision_tile(uint32_t tile_attributes)
- {
- (void) tile_attributes;
- }
-
- const Vector& get_pos() const
- {
- return bbox.p1;
- }
-
- /** returns the bounding box of the Object */
- const Rect& get_bbox() const
- {
- return bbox;
- }
-
- const Vector& get_movement() const
- {
- return movement;
- }
-
- /** places the moving object at a specific position. Be careful when
- * using this function. There are no collision detection checks performed
- * here so bad things could happen.
- */
- virtual void set_pos(const Vector& pos)
- {
- dest.move(pos-get_pos());
- bbox.set_pos(pos);
- }
-
- /**
- * sets the moving object's bbox to a specific width. Be careful when
- * using this function. There are no collision detection checks performed
- * here so bad things could happen.
- */
- virtual void set_width(float w)
- {
- dest.set_width(w);
- bbox.set_width(w);
- }
-
- /**
- * sets the moving object's bbox to a specific size. Be careful when
- * using this function. There are no collision detection checks performed
- * here so bad things could happen.
- */
- virtual void set_size(float w, float h)
- {
- dest.set_size(w, h);
- bbox.set_size(w, h);
- }
-
- CollisionGroup get_group() const
- {
- return group;
- }
-
-protected:
- friend class Sector;
- friend class CollisionGrid;
- friend class Platform;
-
- void set_group(CollisionGroup group)
- {
- this->group = group;
- }
-
- /** The bounding box of the object (as used for collision detection, this
- * isn't necessarily the bounding box for graphics)
- */
- Rect bbox;
- /** The movement that will happen till next frame
- */
- Vector movement;
- /** The collision group */
- CollisionGroup group;
-
-private:
- /**
- * this is only here for internal collision detection use (don't touch this
- * from outside collision detection code)
- *
- * This field holds the currently anticipated destination of the object
- * during collision detection
- */
- Rect dest;
-};
-
-#endif
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <math.h>
-#include <stdexcept>
-#include <iostream>
#include <limits>
+#include <math.h>
-#include "ambient_sound.hpp"
-#include "object_factory.hpp"
-#include "lisp/lisp.hpp"
-#include "sector.hpp"
#include "audio/sound_manager.hpp"
#include "audio/sound_source.hpp"
-#include "log.hpp"
-#include "scripting/squirrel_util.hpp"
+#include "object/ambient_sound.hpp"
#include "object/camera.hpp"
+#include "scripting/squirrel_util.hpp"
+#include "supertux/object_factory.hpp"
+#include "supertux/sector.hpp"
+#include "util/reader.hpp"
-AmbientSound::AmbientSound(const lisp::Lisp& lisp)
+AmbientSound::AmbientSound(const Reader& lisp)
{
name="";
position.x = 0;
// set default silence_distance
if (distance_factor == 0)
- silence_distance = std::numeric_limits<float>::max();
+ silence_distance = std::numeric_limits<float>::max();
else
silence_distance = 1/distance_factor;
// set default silence_distance
if (distance_factor == 0)
- silence_distance = std::numeric_limits<float>::max();
+ silence_distance = std::numeric_limits<float>::max();
else
silence_distance = 1/distance_factor;
}
IMPLEMENT_FACTORY(AmbientSound, "ambient_sound");
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
/**
* Ambient Sound Source, gamma version. Features:
* basti_
*/
-#ifndef __AMBIENT_SOUND_H__
-#define __AMBIENT_SOUND_H__
+#ifndef HEADER_SUPERTUX_OBJECT_AMBIENT_SOUND_HPP
+#define HEADER_SUPERTUX_OBJECT_AMBIENT_SOUND_HPP
-#include "game_object.hpp"
-#include "resources.hpp"
-#include "player.hpp"
-#include "script_interface.hpp"
#include "scripting/ambient_sound.hpp"
+#include "supertux/game_object.hpp"
+#include "supertux/script_interface.hpp"
+#include "util/reader_fwd.hpp"
+class Player;
class SoundSource;
-class AmbientSound : public GameObject, public ScriptInterface, public Scripting::AmbientSound
+class AmbientSound : public GameObject,
+ public ScriptInterface,
+ public Scripting::AmbientSound
{
public:
- AmbientSound(const lisp::Lisp& lisp);
+ AmbientSound(const Reader& lisp);
AmbientSound(Vector pos, float factor, float bias, float vol, std::string file);
~AmbientSound();
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#include "object/anchor_point.hpp"
#include <config.h>
#include <stdexcept>
#include <sstream>
-#include "anchor_point.hpp"
+
#include "math/rect.hpp"
-#include "log.hpp"
+#include "util/log.hpp"
std::string anchor_point_to_string(AnchorPoint point)
{
return result;
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __ANCHOR_POINT_HPP__
-#define __ANCHOR_POINT_HPP__
+#ifndef HEADER_SUPERTUX_OBJECT_ANCHOR_POINT_HPP
+#define HEADER_SUPERTUX_OBJECT_ANCHOR_POINT_HPP
#include <string>
+
#include "math/vector.hpp"
class Rect;
ANCHOR_TOP_LEFT = ANCHOR_TOP | ANCHOR_LEFT,
ANCHOR_TOP_RIGHT = ANCHOR_TOP | ANCHOR_RIGHT,
ANCHOR_BOTTOM_LEFT = ANCHOR_BOTTOM | ANCHOR_LEFT,
- ANCHOR_BOTTOM_RIGHT = ANCHOR_BOTTOM | ANCHOR_RIGHT,
+ ANCHOR_BOTTOM_RIGHT = ANCHOR_BOTTOM | ANCHOR_RIGHT
};
std::string anchor_point_to_string(AnchorPoint point);
AnchorPoint point);
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <stdexcept>
-#include "background.hpp"
-#include "camera.hpp"
-#include "video/drawing_context.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
-#include "resources.hpp"
-#include "main.hpp"
-#include "log.hpp"
+#include "object/background.hpp"
+#include "supertux/main.hpp"
+#include "supertux/object_factory.hpp"
+#include "util/reader.hpp"
Background::Background()
: layer(LAYER_BACKGROUND0)
{
}
-Background::Background(const lisp::Lisp& reader)
+Background::Background(const Reader& reader)
: layer(LAYER_BACKGROUND0)
{
// read position, defaults to (0,0)
}
void
-Background::write(lisp::Writer& writer)
-{
- writer.start_list("background");
-
- if (image_top.get() != NULL)
- writer.write("image-top", imagefile_top);
-
- writer.write("image", imagefile);
- if (image_bottom.get() != NULL)
- writer.write("image-bottom", imagefile_bottom);
-
- writer.write("speed", speed);
- writer.write("speed-y", speed_y);
- writer.write("layer", layer);
-
- writer.end_list("background");
-}
-
-void
Background::update(float)
{
}
}
IMPLEMENT_FACTORY(Background, "background");
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef SUPERTUX_BACKGROUND_H
-#define SUPERTUX_BACKGROUND_H
+#ifndef HEADER_SUPERTUX_OBJECT_BACKGROUND_HPP
+#define HEADER_SUPERTUX_OBJECT_BACKGROUND_HPP
-#include <memory>
-#include "video/surface.hpp"
+#include "supertux/game_object.hpp"
+#include "util/reader_fwd.hpp"
#include "video/drawing_context.hpp"
-#include "game_object.hpp"
-#include "serializable.hpp"
class DisplayManager;
-namespace lisp {
-class Lisp;
-}
-
-class Background : public GameObject, public Serializable
+class Background : public GameObject
{
public:
Background();
- Background(const lisp::Lisp& reader);
+ Background(const Reader& reader);
virtual ~Background();
- virtual void write(lisp::Writer& writer);
-
void set_image(const std::string& name, float bkgd_speed);
std::string get_image() const
};
#endif /*SUPERTUX_BACKGROUND_H*/
+
+/* EOF */
-// $Id$
-//
// SuperTux - BicyclePlatform
// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "bicycle_platform.hpp"
+#include "object/bicycle_platform.hpp"
#include <math.h>
-#include <stdexcept>
-#include "log.hpp"
-#include "video/drawing_context.hpp"
-#include "resources.hpp"
-#include "player.hpp"
-#include "path.hpp"
-#include "path_walker.hpp"
-#include "sprite/sprite.hpp"
-#include "lisp/lisp.hpp"
-#include "object_factory.hpp"
-#include "sector.hpp"
-#include "object/portable.hpp"
-BicyclePlatform::BicyclePlatform(const lisp::Lisp& reader)
- : MovingSprite(reader, LAYER_OBJECTS, COLGROUP_STATIC),
- master(0), slave(0), radius(128), angle(0), angular_speed(0), momentum(0)
+#include "object/player.hpp"
+#include "object/portable.hpp"
+#include "supertux/object_factory.hpp"
+#include "supertux/sector.hpp"
+
+BicyclePlatform::BicyclePlatform(const Reader& reader) :
+ MovingSprite(reader, LAYER_OBJECTS, COLGROUP_STATIC),
+ master(0),
+ slave(0),
+ radius(128),
+ angle(0),
+ angular_speed(0),
+ momentum(0)
{
center = get_pos();
}
-BicyclePlatform::BicyclePlatform(BicyclePlatform* master)
- : MovingSprite(*master),
- master(master), slave(this), center(master->center), radius(master->radius), angle(master->angle + M_PI), angular_speed(0), momentum(0)
+BicyclePlatform::BicyclePlatform(BicyclePlatform* master) :
+ MovingSprite(*master),
+ master(master),
+ slave(this),
+ center(master->center),
+ radius(master->radius),
+ angle(master->angle + M_PI),
+ angular_speed(0),
+ momentum(0)
{
set_pos(get_pos() + Vector(master->get_bbox().get_width(), 0));
master->master = master;
master->slave = this;
}
-BicyclePlatform::~BicyclePlatform() {
+BicyclePlatform::~BicyclePlatform()
+{
if ((this == master) && (master)) {
slave->master = 0;
slave->slave = 0;
IMPLEMENT_FACTORY(BicyclePlatform, "bicycle-platform");
+/* EOF */
-// $Id$
-//
// SuperTux - BicyclePlatform
// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __BICYCLE_PLATFORM_H__
-#define __BICYCLE_PLATFORM_H__
+#ifndef HEADER_SUPERTUX_OBJECT_BICYCLE_PLATFORM_HPP
+#define HEADER_SUPERTUX_OBJECT_BICYCLE_PLATFORM_HPP
-#include <memory>
-#include <string>
-#include <set>
#include "object/moving_sprite.hpp"
-#include "object/path.hpp"
-#include "object/path_walker.hpp"
/**
* Used to construct a pair of bicycle platforms: If one is pushed down, the other one rises
class BicyclePlatform : public MovingSprite
{
public:
- BicyclePlatform(const lisp::Lisp& reader);
+ BicyclePlatform(const Reader& reader);
BicyclePlatform(BicyclePlatform* master);
virtual ~BicyclePlatform();
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
-
-#include "block.hpp"
-
-#include "log.hpp"
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <stdexcept>
+#include "object/block.hpp"
#include "audio/sound_manager.hpp"
#include "badguy/badguy.hpp"
-#include "constants.hpp"
-#include "coin.hpp"
-#include "flower.hpp"
-#include "gameobjs.hpp"
-#include "growup.hpp"
-#include "level.hpp"
-#include "lisp/lisp.hpp"
#include "lisp/list_iterator.hpp"
-#include "moving_object.hpp"
-#include "object_factory.hpp"
-#include "oneup.hpp"
-#include "player.hpp"
-#include "portable.hpp"
-#include "sector.hpp"
-#include "specialriser.hpp"
-#include "sprite/sprite.hpp"
+#include "object/broken_brick.hpp"
+#include "object/coin.hpp"
+#include "object/flower.hpp"
+#include "object/bouncy_coin.hpp"
+#include "object/growup.hpp"
+#include "object/oneup.hpp"
+#include "object/player.hpp"
+#include "object/portable.hpp"
+#include "object/specialriser.hpp"
+#include "object/star.hpp"
#include "sprite/sprite_manager.hpp"
-#include "star.hpp"
+#include "supertux/constants.hpp"
+#include "supertux/level.hpp"
+#include "supertux/object_factory.hpp"
+#include "supertux/sector.hpp"
static const float BOUNCY_BRICK_MAX_OFFSET = 8;
static const float BOUNCY_BRICK_SPEED = 90;
static const float EPSILON = .0001f;
static const float BUMP_ROTATION_ANGLE = 10;
-Block::Block(Sprite* newsprite)
- : sprite(newsprite), bouncing(false), breaking(false), bounce_dir(0), bounce_offset(0), original_y(-1)
+Block::Block(std::auto_ptr<Sprite> newsprite) :
+ sprite(newsprite),
+ bouncing(false),
+ breaking(false),
+ bounce_dir(0),
+ bounce_offset(0),
+ original_y(-1)
{
bbox.set_size(32, 32.1f);
set_group(COLGROUP_STATIC);
Block::~Block()
{
- delete sprite;
}
HitResponse
//---------------------------------------------------------------------------
-BonusBlock::BonusBlock(const Vector& pos, int data)
- : Block(sprite_manager->create("images/objects/bonus_block/bonusblock.sprite")), object(0)
+BonusBlock::BonusBlock(const Vector& pos, int data) :
+ Block(sprite_manager->create("images/objects/bonus_block/bonusblock.sprite")),
+ object(0)
{
bbox.set_pos(pos);
sprite->set_action("normal");
}
}
-BonusBlock::BonusBlock(const lisp::Lisp& lisp)
- : Block(sprite_manager->create("images/objects/bonus_block/bonusblock.sprite"))
+BonusBlock::BonusBlock(const Reader& lisp) :
+ Block(sprite_manager->create("images/objects/bonus_block/bonusblock.sprite"))
{
Vector pos;
HitResponse
BonusBlock::collision(GameObject& other, const CollisionHit& hit){
- Player* player = dynamic_cast<Player*> (&other);
- if (player) {
- if (player->does_buttjump) try_open();
- }
+ Player* player = dynamic_cast<Player*> (&other);
+ if (player) {
+ if (player->does_buttjump) try_open();
+ }
- BadGuy* badguy = dynamic_cast<BadGuy*> (&other);
- if(badguy) {
- // hit contains no information for collisions with blocks.
- // Badguy's bottom has to be below the top of the block
- // SHIFT_DELTA is required to slide over one tile gaps.
- if( badguy->can_break() && ( badguy->get_bbox().get_bottom() > get_bbox().get_top() + SHIFT_DELTA ) ){
- try_open();
- }
+ BadGuy* badguy = dynamic_cast<BadGuy*> (&other);
+ if(badguy) {
+ // hit contains no information for collisions with blocks.
+ // Badguy's bottom has to be below the top of the block
+ // SHIFT_DELTA is required to slide over one tile gaps.
+ if( badguy->can_break() && ( badguy->get_bbox().get_bottom() > get_bbox().get_top() + SHIFT_DELTA ) ){
+ try_open();
}
- Portable* portable = dynamic_cast<Portable*> (&other);
- if(portable) {
- MovingObject* moving = dynamic_cast<MovingObject*> (&other);
- if(moving->get_bbox().get_top() > get_bbox().get_bottom() - SHIFT_DELTA) {
- try_open();
- }
+ }
+ Portable* portable = dynamic_cast<Portable*> (&other);
+ if(portable) {
+ MovingObject* moving = dynamic_cast<MovingObject*> (&other);
+ if(moving->get_bbox().get_top() > get_bbox().get_bottom() - SHIFT_DELTA) {
+ try_open();
}
- return Block::collision(other, hit);
+ }
+ return Block::collision(other, hit);
}
void
sector->add_object(riser);
} else {
SpecialRiser* riser = new SpecialRiser(
- get_pos(), new Flower(FIRE_BONUS));
+ get_pos(), new Flower(FIRE_BONUS));
sector->add_object(riser);
}
sound_manager->play("sounds/upgrade.wav");
sector->add_object(riser);
} else {
SpecialRiser* riser = new SpecialRiser(
- get_pos(), new Flower(ICE_BONUS));
+ get_pos(), new Flower(ICE_BONUS));
sector->add_object(riser);
}
sound_manager->play("sounds/upgrade.wav");
{
Sector* sector = Sector::current();
sector->add_object(
- new BrokenBrick(new Sprite(*sprite), get_pos(), Vector(-100, -400)));
+ new BrokenBrick(std::auto_ptr<Sprite>(new Sprite(*sprite)), get_pos(), Vector(-100, -400)));
sector->add_object(
- new BrokenBrick(new Sprite(*sprite), get_pos() + Vector(0, 16),
- Vector(-150, -300)));
+ new BrokenBrick(std::auto_ptr<Sprite>(new Sprite(*sprite)), get_pos() + Vector(0, 16),
+ Vector(-150, -300)));
sector->add_object(
- new BrokenBrick(new Sprite(*sprite), get_pos() + Vector(16, 0),
- Vector(100, -400)));
+ new BrokenBrick(std::auto_ptr<Sprite>(new Sprite(*sprite)), get_pos() + Vector(16, 0),
+ Vector(100, -400)));
sector->add_object(
- new BrokenBrick(new Sprite(*sprite), get_pos() + Vector(16, 16),
- Vector(150, -300)));
+ new BrokenBrick(std::auto_ptr<Sprite>(new Sprite(*sprite)), get_pos() + Vector(16, 16),
+ Vector(150, -300)));
remove_me();
}
HitResponse
Brick::collision(GameObject& other, const CollisionHit& hit){
- Player* player = dynamic_cast<Player*> (&other);
- if (player) {
- if (player->does_buttjump) try_break();
- }
+ Player* player = dynamic_cast<Player*> (&other);
+ if (player) {
+ if (player->does_buttjump) try_break();
+ }
- BadGuy* badguy = dynamic_cast<BadGuy*> (&other);
- if(badguy) {
- // hit contains no information for collisions with blocks.
- // Badguy's bottom has to be below the top of the brick
- // SHIFT_DELTA is required to slide over one tile gaps.
- if( badguy->can_break() && ( badguy->get_bbox().get_bottom() > get_bbox().get_top() + SHIFT_DELTA ) ){
- try_break();
- }
+ BadGuy* badguy = dynamic_cast<BadGuy*> (&other);
+ if(badguy) {
+ // hit contains no information for collisions with blocks.
+ // Badguy's bottom has to be below the top of the brick
+ // SHIFT_DELTA is required to slide over one tile gaps.
+ if( badguy->can_break() && ( badguy->get_bbox().get_bottom() > get_bbox().get_top() + SHIFT_DELTA ) ){
+ try_break();
}
- Portable* portable = dynamic_cast<Portable*> (&other);
- if(portable) {
- MovingObject* moving = dynamic_cast<MovingObject*> (&other);
- if(moving->get_bbox().get_top() > get_bbox().get_bottom() - SHIFT_DELTA) {
- try_break();
- }
+ }
+ Portable* portable = dynamic_cast<Portable*> (&other);
+ if(portable) {
+ MovingObject* moving = dynamic_cast<MovingObject*> (&other);
+ if(moving->get_bbox().get_top() > get_bbox().get_bottom() - SHIFT_DELTA) {
+ try_break();
}
- return Block::collision(other, hit);
+ }
+ return Block::collision(other, hit);
}
void
return;
}
}
- break_me();
+ break_me();
}
}
//IMPLEMENT_FACTORY(Brick, "brick");
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_OBJECT_BLOCK_HPP
+#define HEADER_SUPERTUX_OBJECT_BLOCK_HPP
-#ifndef __BLOCK_H__
-#define __BLOCK_H__
+#include <memory>
-#include "moving_object.hpp"
-#include "lisp/lisp.hpp"
+#include "supertux/moving_object.hpp"
+#include "util/reader_fwd.hpp"
class Sprite;
class Player;
class Block : public MovingObject
{
public:
- Block(Sprite* sprite = 0);
+ Block(std::auto_ptr<Sprite> sprite);
~Block();
virtual HitResponse collision(GameObject& other, const CollisionHit& hit);
void start_break(GameObject* hitter);
void break_me();
- Sprite* sprite;
+ std::auto_ptr<Sprite> sprite;
bool bouncing;
bool breaking;
float bounce_dir;
float bounce_offset;
float original_y;
+private:
+ Block(const Block&);
+ Block& operator=(const Block&);
};
class BonusBlock : public Block
{
public:
BonusBlock(const Vector& pos, int data);
- BonusBlock(const lisp::Lisp& lisp);
+ BonusBlock(const Reader& lisp);
virtual ~BonusBlock();
HitResponse collision(GameObject& other, const CollisionHit& hit);
};
#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include "object/bouncy_coin.hpp"
+
+#include "sprite/sprite.hpp"
+#include "sprite/sprite_manager.hpp"
+
+/** this controls the time over which a bouncy coin fades */
+static const float FADE_TIME = .2f;
+/** this is the total life time of a bouncy coin */
+static const float LIFE_TIME = .5f;
+
+BouncyCoin::BouncyCoin(const Vector& pos, bool emerge) :
+ position(pos),
+ emerge_distance(0)
+{
+ timer.start(LIFE_TIME);
+ sprite = sprite_manager->create("images/objects/coin/coin.sprite");
+
+ if(emerge) {
+ emerge_distance = sprite->get_height();
+ }
+}
+
+BouncyCoin::~BouncyCoin()
+{
+}
+
+void
+BouncyCoin::update(float elapsed_time)
+{
+ float dist = -200 * elapsed_time;
+ position.y += dist;
+ emerge_distance += dist;
+
+ if(timer.check())
+ remove_me();
+}
+
+void
+BouncyCoin::draw(DrawingContext& context)
+{
+ float time_left = timer.get_timeleft();
+ bool fading = time_left < FADE_TIME;
+ if(fading) {
+ float alpha = time_left/FADE_TIME;
+ context.push_transform();
+ context.set_alpha(alpha);
+ }
+
+ int layer;
+ if(emerge_distance > 0) {
+ layer = LAYER_OBJECTS - 5;
+ } else {
+ layer = LAYER_OBJECTS + 5;
+ }
+ sprite->draw(context, position, layer);
+
+ if(fading) {
+ context.pop_transform();
+ }
+}
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_OBJECT_BOUNCY_COIN_HPP
+#define HEADER_SUPERTUX_OBJECT_BOUNCY_COIN_HPP
+
+#include <memory>
+
+#include "math/vector.hpp"
+#include "supertux/game_object.hpp"
+#include "supertux/timer.hpp"
+#include "video/color.hpp"
+
+class Sprite;
+
+class BouncyCoin : public GameObject
+{
+public:
+ BouncyCoin(const Vector& pos, bool emerge=false);
+ ~BouncyCoin();
+ virtual void update(float elapsed_time);
+ virtual void draw(DrawingContext& context);
+
+private:
+ std::auto_ptr<Sprite> sprite;
+ Vector position;
+ Timer timer;
+ float emerge_distance;
+
+private:
+ BouncyCoin(const BouncyCoin&);
+ BouncyCoin& operator=(const BouncyCoin&);
+};
+
+#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include "object/broken_brick.hpp"
+
+#include "math/random_generator.hpp"
+#include "sprite/sprite.hpp"
+
+BrokenBrick::BrokenBrick(std::auto_ptr<Sprite> sprite,
+ const Vector& pos, const Vector& nmovement) :
+ sprite(sprite),
+ position(pos),
+ movement(nmovement)
+{
+ timer.start(.2f);
+}
+
+BrokenBrick::~BrokenBrick()
+{
+}
+
+void
+BrokenBrick::update(float elapsed_time)
+{
+ position += movement * elapsed_time;
+
+ if (timer.check())
+ remove_me();
+}
+
+void
+BrokenBrick::draw(DrawingContext& context)
+{
+ sprite->draw_part(context,
+ Vector(systemRandom.rand(16), systemRandom.rand(16)), Vector(16, 16),
+ position, LAYER_OBJECTS + 1);
+}
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_OBJECT_BROKEN_BRICK_HPP
+#define HEADER_SUPERTUX_OBJECT_BROKEN_BRICK_HPP
+
+#include <memory>
+
+#include "math/vector.hpp"
+#include "supertux/game_object.hpp"
+#include "supertux/timer.hpp"
+#include "video/color.hpp"
+
+class Sprite;
+
+class BrokenBrick : public GameObject
+{
+public:
+ BrokenBrick(std::auto_ptr<Sprite> sprite, const Vector& pos, const Vector& movement);
+ ~BrokenBrick();
+
+ virtual void update(float elapsed_time);
+ virtual void draw(DrawingContext& context);
+
+private:
+ Timer timer;
+ std::auto_ptr<Sprite> sprite;
+ Vector position;
+ Vector movement;
+
+private:
+ BrokenBrick(const BrokenBrick&);
+ BrokenBrick& operator=(const BrokenBrick&);
+};
+
+#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <math.h>
-#include "bullet.hpp"
-#include "resources.hpp"
-#include "camera.hpp"
-#include "sector.hpp"
+#include "object/bullet.hpp"
+#include "object/camera.hpp"
#include "sprite/sprite_manager.hpp"
-#include "badguy/badguy.hpp"
-#include "main.hpp"
+#include "supertux/main.hpp"
+#include "supertux/sector.hpp"
namespace {
- const float BULLET_XM = 600;
- const float BULLET_STARTING_YM = 0;
+const float BULLET_XM = 600;
+const float BULLET_STARTING_YM = 0;
}
Bullet::Bullet(const Vector& pos, float xm, int dir, BonusType type)
physic.set_velocity_x(speed + xm);
if(type == FIRE_BONUS) {
- sprite.reset(sprite_manager->create("images/objects/bullets/firebullet.sprite"));
+ sprite = sprite_manager->create("images/objects/bullets/firebullet.sprite");
} else if(type == ICE_BONUS) {
life_count = 10;
- sprite.reset(sprite_manager->create("images/objects/bullets/icebullet.sprite"));
+ sprite = sprite_manager->create("images/objects/bullets/icebullet.sprite");
} else {
log_warning << "Bullet::Bullet called with unknown BonusType" << std::endl;
life_count = 10;
- sprite.reset(sprite_manager->create("images/objects/bullets/firebullet.sprite"));
+ sprite = sprite_manager->create("images/objects/bullets/firebullet.sprite");
}
bbox.set_pos(pos);
Sector::current()->camera->get_translation().y;
if (get_pos().x < scroll_x ||
get_pos().x > scroll_x + SCREEN_WIDTH ||
-// get_pos().y < scroll_y ||
+ // get_pos().y < scroll_y ||
get_pos().y > scroll_y + SCREEN_HEIGHT ||
life_count <= 0) {
remove_me();
{
return FORCE_MOVE;
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __BULLET_H__
-#define __BULLET_H__
+#ifndef HEADER_SUPERTUX_OBJECT_BULLET_HPP
+#define HEADER_SUPERTUX_OBJECT_BULLET_HPP
-#include "moving_object.hpp"
-#include "physic.hpp"
#include "sprite/sprite.hpp"
-#include "player_status.hpp"
+#include "supertux/moving_object.hpp"
+#include "supertux/physic.hpp"
+#include "supertux/player_status.hpp"
-class Bullet : public MovingObject, private UsesPhysic
+class Bullet : public MovingObject
{
public:
Bullet(const Vector& pos, float xm, int dir, BonusType type);
}
private:
+ Physic physic;
int life_count;
std::auto_ptr<Sprite> sprite;
BonusType type;
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "camera.hpp"
+#include "object/camera.hpp"
-#include <stdexcept>
-#include <sstream>
#include <cmath>
#include <physfs.h>
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-#include "lisp/list_iterator.hpp"
+#include "util/reader.hpp"
+#include "util/writer.hpp"
#include "lisp/parser.hpp"
+#include "object/path_walker.hpp"
+#include "object/player.hpp"
#include "scripting/camera.hpp"
#include "scripting/squirrel_util.hpp"
-#include "player.hpp"
-#include "tilemap.hpp"
-#include "game_session.hpp"
-#include "sector.hpp"
-#include "main.hpp"
-#include "object_factory.hpp"
-#include "log.hpp"
-#include "path.hpp"
-#include "path_walker.hpp"
+#include "supertux/main.hpp"
+#include "supertux/sector.hpp"
/* this is the fractional distance toward the peek
position to move each frame; lower is slower,
}
void
-Camera::parse(const lisp::Lisp& reader)
+Camera::parse(const Reader& reader)
{
std::string modename;
}
void
-Camera::write(lisp::Writer& writer)
-{
- writer.start_list("camera");
-
- if(mode == NORMAL) {
- writer.write("mode", "normal");
- } else if(mode == AUTOSCROLL) {
- writer.write("mode", "autoscroll");
- autoscroll_path->write(writer);
- } else if(mode == MANUAL) {
- writer.write("mode", "manual");
- }
-
- writer.end_list("camera");
-}
-
-void
Camera::reset(const Vector& tuxpos)
{
translation.x = tuxpos.x - SCREEN_WIDTH/2;
log_info << "Loaded camera.cfg." << std::endl;
} catch(std::exception &e) {
log_debug << "Couldn't load camera.cfg, using defaults ("
- << e.what() << ")" << std::endl;
+ << e.what() << ")" << std::endl;
}
}
}
// limit the camera speed when jumping upwards
if(player->fall_mode != Player::FALLING
- && player->fall_mode != Player::TRAMPOLINE_JUMP) {
+ && player->fall_mode != Player::TRAMPOLINE_JUMP) {
speed_y = clamp(speed_y, -config.max_speed_y, config.max_speed_y);
}
if(ymode == 3) {
float halfsize = config.kirby_rectsize_y * 0.5f;
cached_translation.y = clamp(cached_translation.y,
- player_pos.y - SCREEN_HEIGHT * (0.5f + halfsize),
- player_pos.y - SCREEN_HEIGHT * (0.5f - halfsize));
+ player_pos.y - SCREEN_HEIGHT * (0.5f + halfsize),
+ player_pos.y - SCREEN_HEIGHT * (0.5f - halfsize));
}
if(ymode == 4) {
float upperend = SCREEN_HEIGHT * config.edge_x;
if(xmode == 3) {
float halfsize = config.kirby_rectsize_x * 0.5f;
cached_translation.x = clamp(cached_translation.x,
- player_pos.x - SCREEN_WIDTH * (0.5f + halfsize),
- player_pos.x - SCREEN_WIDTH * (0.5f - halfsize));
+ player_pos.x - SCREEN_WIDTH * (0.5f + halfsize),
+ player_pos.x - SCREEN_WIDTH * (0.5f - halfsize));
}
if(xmode == 4) {
float LEFTEND = SCREEN_WIDTH * config.edge_x;
// walking right
lookahead_pos.x -= player_delta.x * config.dynamic_speed_sm;
if(lookahead_pos.x < LEFTEND) {
- lookahead_pos.x = LEFTEND;
+ lookahead_pos.x = LEFTEND;
}
}
return translation + Vector(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2);
}
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#ifndef SUPERTUX_CAMERA_H
-#define SUPERTUX_CAMERA_H
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_OBJECT_CAMERA_HPP
+#define HEADER_SUPERTUX_OBJECT_CAMERA_HPP
-#include <vector>
-#include <cassert>
#include <memory>
#include "math/vector.hpp"
-#include "game_object.hpp"
-#include "video/drawing_context.hpp"
-#include "serializable.hpp"
-#include "timer.hpp"
-#include "script_interface.hpp"
-
-namespace lisp {
-class Lisp;
-}
+#include "supertux/game_object.hpp"
+#include "supertux/script_interface.hpp"
+#include "supertux/timer.hpp"
+#include "util/reader_fwd.hpp"
class Sector;
class Path;
class PathWalker;
class CameraConfig;
-class Camera : public GameObject, public Serializable, public ScriptInterface
+class Camera : public GameObject,
+ public ScriptInterface
{
public:
Camera(Sector* sector, std::string name = "");
virtual ~Camera();
/// parse camera mode from lisp file
- void parse(const lisp::Lisp& reader);
- /// write camera mode to a lisp file
- virtual void write(lisp::Writer& writer);
-
+ void parse(const Reader& reader);
+
/// reset camera position
void reset(const Vector& tuxpos);
float scrollspeed;
CameraConfig *config;
+
+private:
+ Camera(const Camera&);
+ Camera& operator=(const Camera&);
};
#endif /*SUPERTUX_CAMERA_H*/
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "candle.hpp"
+#include "math/random_generator.hpp"
+#include "object/candle.hpp"
+#include "object/sprite_particle.hpp"
#include "scripting/candle.hpp"
#include "scripting/squirrel_util.hpp"
-#include "sector.hpp"
-#include "object/sprite_particle.hpp"
-#include "object_factory.hpp"
-#include "random_generator.hpp"
+#include "supertux/object_factory.hpp"
+#include "supertux/sector.hpp"
-Candle::Candle(const lisp::Lisp& lisp)
- : MovingSprite(lisp, "images/objects/candle/candle.sprite", LAYER_BACKGROUNDTILES+1, COLGROUP_DISABLED), burning(true),
- candle_light_1("images/objects/candle/candle-light-1.png"),
- candle_light_2("images/objects/candle/candle-light-2.png")
+Candle::Candle(const Reader& lisp)
+ : MovingSprite(lisp, "images/objects/candle/candle.sprite", LAYER_BACKGROUNDTILES+1, COLGROUP_DISABLED), burning(true),
+ candle_light_1("images/objects/candle/candle-light-1.png"),
+ candle_light_2("images/objects/candle/candle-light-2.png")
{
lisp.get("name", name);
lisp.get("burning", burning);
}
IMPLEMENT_FACTORY(Candle, "candle");
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#ifndef __CANDLE_H__
-#define __CANDLE_H__
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <string>
+#ifndef HEADER_SUPERTUX_OBJECT_CANDLE_HPP
+#define HEADER_SUPERTUX_OBJECT_CANDLE_HPP
-#include "lisp/lisp.hpp"
#include "object/moving_sprite.hpp"
-#include "script_interface.hpp"
-#include "video/surface.hpp"
+#include "supertux/script_interface.hpp"
/**
* A burning candle: Simple, scriptable level decoration.
*/
-class Candle : public MovingSprite, public ScriptInterface
+class Candle : public MovingSprite,
+ public ScriptInterface
{
public:
- Candle(const lisp::Lisp& lisp);
- virtual Candle* clone() const { return new Candle(*this); }
+ Candle(const Reader& lisp);
virtual void draw(DrawingContext& context);
HitResponse collision(GameObject& other, const CollisionHit& hit);
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <config.h>
+#include "object/coin.hpp"
-#include "coin.hpp"
-#include "resources.hpp"
-#include "video/drawing_context.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "player.hpp"
-#include "sector.hpp"
-#include "player_status.hpp"
-#include "gameobjs.hpp"
-#include "statistics.hpp"
-#include "object_factory.hpp"
-#include "level.hpp"
-#include "random_generator.hpp"
-#include "audio/sound_source.hpp"
#include "audio/sound_manager.hpp"
-#include "timer.hpp"
+#include "object/bouncy_coin.hpp"
+#include "object/player.hpp"
+#include "supertux/level.hpp"
+#include "supertux/object_factory.hpp"
+#include "supertux/sector.hpp"
Coin::Coin(const Vector& pos)
- : MovingSprite(pos, "images/objects/coin/coin.sprite", LAYER_TILES, COLGROUP_TOUCHABLE)
+ : MovingSprite(pos, "images/objects/coin/coin.sprite", LAYER_TILES, COLGROUP_TOUCHABLE)
{
sound_manager->preload("sounds/coin.wav");
}
-Coin::Coin(const lisp::Lisp& reader)
- : MovingSprite(reader, "images/objects/coin/coin.sprite", LAYER_TILES, COLGROUP_TOUCHABLE)
+Coin::Coin(const Reader& reader)
+ : MovingSprite(reader, "images/objects/coin/coin.sprite", LAYER_TILES, COLGROUP_TOUCHABLE)
{
sound_manager->preload("sounds/coin.wav");
}
{
// TODO: commented out musical code. Maybe fork this for a special "MusicalCoin" object?
/*
- static Timer sound_timer;
- static int pitch_one = 128;
- static float last_pitch = 1;
- float pitch = 1;
+ static Timer sound_timer;
+ static int pitch_one = 128;
+ static float last_pitch = 1;
+ float pitch = 1;
- int tile = static_cast<int>(get_pos().y / 32);
+ int tile = static_cast<int>(get_pos().y / 32);
- if (!sound_timer.started()) {
+ if (!sound_timer.started()) {
pitch_one = tile;
pitch = 1;
last_pitch = 1;
- }
- else if (sound_timer.get_timegone() < 0.02) {
+ }
+ else if (sound_timer.get_timegone() < 0.02) {
pitch = last_pitch;
- }
- else
- {
+ }
+ else
+ {
switch ((pitch_one - tile) % 7) {
- case -6:
- pitch = 1.0/2;
- break;
- case -5:
- pitch = 5.0/8;
- break;
- case -4:
- pitch = 4.0/6;
- break;
- case -3:
- pitch = 3.0/4;
- break;
- case -2:
- pitch = 5.0/6;
- break;
- case -1:
- pitch = 9.0/10;
- break;
- case 0:
- pitch = 1.0;
- break;
- case 1:
- pitch = 9.0/8;
- break;
- case 2:
- pitch = 5.0/4;
- break;
- case 3:
- pitch = 4.0/3;
- break;
- case 4:
- pitch = 3.0/2;
- break;
- case 5:
- pitch = 5.0/3;
- break;
- case 6:
- pitch = 9.0/5;
- break;
+ case -6:
+ pitch = 1.0/2;
+ break;
+ case -5:
+ pitch = 5.0/8;
+ break;
+ case -4:
+ pitch = 4.0/6;
+ break;
+ case -3:
+ pitch = 3.0/4;
+ break;
+ case -2:
+ pitch = 5.0/6;
+ break;
+ case -1:
+ pitch = 9.0/10;
+ break;
+ case 0:
+ pitch = 1.0;
+ break;
+ case 1:
+ pitch = 9.0/8;
+ break;
+ case 2:
+ pitch = 5.0/4;
+ break;
+ case 3:
+ pitch = 4.0/3;
+ break;
+ case 4:
+ pitch = 3.0/2;
+ break;
+ case 5:
+ pitch = 5.0/3;
+ break;
+ case 6:
+ pitch = 9.0/5;
+ break;
}
last_pitch = pitch;
- }
- sound_timer.start(1);
+ }
+ sound_timer.start(1);
- SoundSource* soundSource = sound_manager->create_sound_source("sounds/coin.wav");
- soundSource->set_position(get_pos());
- soundSource->set_pitch(pitch);
- soundSource->play();
- sound_manager->manage_source(soundSource);
-*/
+ SoundSource* soundSource = sound_manager->create_sound_source("sounds/coin.wav");
+ soundSource->set_position(get_pos());
+ soundSource->set_pitch(pitch);
+ soundSource->play();
+ sound_manager->manage_source(soundSource);
+ */
Sector::current()->player->get_status()->add_coins(1);
Sector::current()->add_object(new BouncyCoin(get_pos()));
Sector::current()->get_level()->stats.coins++;
}
IMPLEMENT_FACTORY(Coin, "coin");
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __COIN_H__
-#define __COIN_H__
+#ifndef HEADER_SUPERTUX_OBJECT_COIN_HPP
+#define HEADER_SUPERTUX_OBJECT_COIN_HPP
-#include "moving_sprite.hpp"
-#include "lisp/lisp.hpp"
+#include "object/moving_sprite.hpp"
class Coin : public MovingSprite
{
public:
Coin(const Vector& pos);
- Coin(const lisp::Lisp& reader);
+ Coin(const Reader& reader);
HitResponse collision(GameObject& other, const CollisionHit& hit);
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux - Decal
// Copyright (C) 2008 Christoph Sommer <christoph.sommer@2008.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <stdexcept>
-#include "decal.hpp"
-#include "camera.hpp"
-#include "video/drawing_context.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
-#include "resources.hpp"
-#include "main.hpp"
-#include "log.hpp"
+#include "object/decal.hpp"
+#include "supertux/object_factory.hpp"
+#include "util/reader.hpp"
-Decal::Decal(const lisp::Lisp& reader)
- : layer(LAYER_OBJECTS)
+Decal::Decal(const Reader& reader) :
+ pos(),
+ imagefile(),
+ layer(LAYER_OBJECTS),
+ image()
{
float px = 0;
float py = 0;
}
void
-Decal::write(lisp::Writer& writer)
-{
- writer.start_list("decal");
- writer.write("x", pos.x);
- writer.write("y", pos.y);
- writer.write("image", imagefile);
- writer.write("layer", layer);
- writer.end_list("decal");
-}
-
-void
Decal::update(float)
{
}
IMPLEMENT_FACTORY(Decal, "decal");
+/* EOF */
-// $Id$
-//
// SuperTux - Decal
// Copyright (C) 2008 Christoph Sommer <christoph.sommer@2008.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef SUPERTUX_DECAL_H
-#define SUPERTUX_DECAL_H
+#ifndef HEADER_SUPERTUX_OBJECT_DECAL_HPP
+#define HEADER_SUPERTUX_OBJECT_DECAL_HPP
-#include <memory>
-#include "video/surface.hpp"
+#include "supertux/game_object.hpp"
+#include "util/reader_fwd.hpp"
#include "video/drawing_context.hpp"
-#include "game_object.hpp"
-#include "serializable.hpp"
class DisplayManager;
-namespace lisp {
-class Lisp;
-}
-
/**
* Non-interactive, decorative image
*/
-class Decal : public GameObject, public Serializable
+class Decal : public GameObject
{
public:
- Decal(const lisp::Lisp& reader);
+ Decal(const Reader& reader);
virtual ~Decal();
- virtual void write(lisp::Writer& writer);
virtual void update(float elapsed_time);
virtual void draw(DrawingContext& context);
#endif /*SUPERTUX_DECAL_H*/
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <config.h>
-#include "display_effect.hpp"
+#include "object/display_effect.hpp"
-#include <assert.h>
-#include "video/drawing_context.hpp"
#include "scripting/squirrel_util.hpp"
-#include "main.hpp"
+#include "supertux/main.hpp"
+#include "video/drawing_context.hpp"
static const float BORDER_SIZE = 75;
-DisplayEffect::DisplayEffect(std::string name)
- : screen_fade(NO_FADE), screen_fadetime(0), screen_fading(0),
- border_fade(NO_FADE), border_fadetime(0), border_size(0), black(false),
- borders(false)
+DisplayEffect::DisplayEffect(std::string name) :
+ screen_fade(NO_FADE),
+ screen_fadetime(0),
+ screen_fading(0),
+ border_fade(NO_FADE),
+ border_fadetime(0),
+ border_size(0),
+ black(false),
+ borders(false)
{
this->name = name;
}
DisplayEffect::update(float elapsed_time)
{
switch(screen_fade) {
- case NO_FADE:
- break;
- case FADE_IN:
- screen_fading -= elapsed_time;
- if(screen_fading < 0) {
- screen_fade = NO_FADE;
- }
- break;
- case FADE_OUT:
- screen_fading -= elapsed_time;
- if(screen_fading < 0) {
- screen_fade = NO_FADE;
- black = true;
- }
- break;
- default:
- assert(false);
+ case NO_FADE:
+ break;
+ case FADE_IN:
+ screen_fading -= elapsed_time;
+ if(screen_fading < 0) {
+ screen_fade = NO_FADE;
+ }
+ break;
+ case FADE_OUT:
+ screen_fading -= elapsed_time;
+ if(screen_fading < 0) {
+ screen_fade = NO_FADE;
+ black = true;
+ }
+ break;
+ default:
+ assert(false);
}
switch(border_fade) {
- case NO_FADE:
- break;
- case FADE_IN:
- border_fading -= elapsed_time;
- if(border_fading < 0) {
- border_fade = NO_FADE;
- }
- border_size = (border_fadetime - border_fading)
- / border_fadetime * BORDER_SIZE;
- break;
- case FADE_OUT:
- border_fading -= elapsed_time;
- if(border_fading < 0) {
- borders = false;
- border_fade = NO_FADE;
- }
- border_size = border_fading / border_fadetime * BORDER_SIZE;
- break;
- default:
- assert(false);
+ case NO_FADE:
+ break;
+ case FADE_IN:
+ border_fading -= elapsed_time;
+ if(border_fading < 0) {
+ border_fade = NO_FADE;
+ }
+ border_size = (border_fadetime - border_fading)
+ / border_fadetime * BORDER_SIZE;
+ break;
+ case FADE_OUT:
+ border_fading -= elapsed_time;
+ if(border_fading < 0) {
+ borders = false;
+ border_fade = NO_FADE;
+ }
+ border_size = border_fading / border_fadetime * BORDER_SIZE;
+ break;
+ default:
+ assert(false);
}
}
alpha = 1.0f;
} else {
switch(screen_fade) {
- case FADE_IN:
- alpha = screen_fading / screen_fadetime;
- break;
- case FADE_OUT:
- alpha = (screen_fadetime - screen_fading) / screen_fadetime;
- break;
- default:
- alpha = 0;
- assert(false);
+ case FADE_IN:
+ alpha = screen_fading / screen_fadetime;
+ break;
+ case FADE_OUT:
+ alpha = (screen_fadetime - screen_fading) / screen_fadetime;
+ break;
+ default:
+ alpha = 0;
+ assert(false);
}
}
context.draw_filled_rect(Vector(0, 0), Vector(SCREEN_WIDTH, SCREEN_HEIGHT),
- Color(0, 0, 0, alpha), LAYER_GUI-10);
+ Color(0, 0, 0, alpha), LAYER_GUI-10);
}
if (borders) {
context.draw_filled_rect(Vector(0, 0), Vector(SCREEN_WIDTH, border_size),
- Color(0, 0, 0, 1.0f), LAYER_GUI-10);
+ Color(0, 0, 0, 1.0f), LAYER_GUI-10);
context.draw_filled_rect(Vector(0, SCREEN_HEIGHT - border_size), Vector(SCREEN_WIDTH, border_size),
- Color(0, 0, 0, 1.0f), LAYER_GUI-10);
+ Color(0, 0, 0, 1.0f), LAYER_GUI-10);
}
context.pop_transform();
border_fading = border_fadetime;
}
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __OBJECT_DISPLAY_EFFECT_H__
-#define __OBJECT_DISPLAY_EFFECT_H__
+#ifndef HEADER_SUPERTUX_OBJECT_DISPLAY_EFFECT_HPP
+#define HEADER_SUPERTUX_OBJECT_DISPLAY_EFFECT_HPP
#include "scripting/display_effect.hpp"
-#include "game_object.hpp"
-#include "script_interface.hpp"
+#include "supertux/game_object.hpp"
+#include "supertux/script_interface.hpp"
-class DisplayEffect : public GameObject, public Scripting::DisplayEffect,
+class DisplayEffect : public GameObject,
+ public Scripting::DisplayEffect,
public ScriptInterface
{
public:
- DisplayEffect(std::string name = "");
- virtual ~DisplayEffect();
-
- void expose(HSQUIRRELVM vm, SQInteger table_idx);
- void unexpose(HSQUIRRELVM vm, SQInteger table_idx);
+ DisplayEffect(std::string name = "");
+ virtual ~DisplayEffect();
- void update(float elapsed_time);
- void draw(DrawingContext& context);
+ void expose(HSQUIRRELVM vm, SQInteger table_idx);
+ void unexpose(HSQUIRRELVM vm, SQInteger table_idx);
+ void update(float elapsed_time);
+ void draw(DrawingContext& context);
- /**
- * @name Scriptable Methods
- * @{
- */
+ /**
+ * @name Scriptable Methods
+ * @{
+ */
- void fade_out(float fadetime);
- void fade_in(float fadetime);
- void set_black(bool enabled);
- bool is_black();
- void sixteen_to_nine(float fadetime);
- void four_to_three(float fadetime);
+ void fade_out(float fadetime);
+ void fade_in(float fadetime);
+ void set_black(bool enabled);
+ bool is_black();
+ void sixteen_to_nine(float fadetime);
+ void four_to_three(float fadetime);
- /**
- * @}
- */
+ /**
+ * @}
+ */
private:
- enum FadeType {
- NO_FADE, FADE_IN, FADE_OUT
- };
- FadeType screen_fade;
- float screen_fadetime;
- float screen_fading;
- FadeType border_fade;
- float border_fadetime;
- float border_fading;
- float border_size;
+ enum FadeType {
+ NO_FADE, FADE_IN, FADE_OUT
+ };
+ FadeType screen_fade;
+ float screen_fadetime;
+ float screen_fading;
+ FadeType border_fade;
+ float border_fadetime;
+ float border_fading;
+ float border_size;
- bool black;
- bool borders;
+ bool black;
+ bool borders;
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
-#include "electrifier.hpp"
-#include "sector.hpp"
-#include "object/tilemap.hpp"
-#include "tile.hpp"
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+#include "object/electrifier.hpp"
+#include "supertux/sector.hpp"
Electrifier::Electrifier(uint32_t oldtile, uint32_t newtile, float seconds)
{
Electrifier::draw(DrawingContext& )
{
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __ELECTRIFIER_H__
-#define __ELECTRIFIER_H__
+#ifndef HEADER_SUPERTUX_OBJECT_ELECTRIFIER_HPP
+#define HEADER_SUPERTUX_OBJECT_ELECTRIFIER_HPP
-#include "resources.hpp"
-#include "game_object.hpp"
-#include "timer.hpp"
+#include "supertux/game_object.hpp"
+#include "supertux/timer.hpp"
#include <stdint.h>
//Changes all tiles with the given ID to a new one for a given amount of time, then removes itself
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux - End Sequence
// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "endsequence.hpp"
+#include "object/endsequence.hpp"
-#include <stdexcept>
-#include <iostream>
-#include <sstream>
-#include "main.hpp"
-#include "resources.hpp"
-#include "sector.hpp"
-#include "gettext.hpp"
-#include "object_factory.hpp"
#include "object/player.hpp"
-#include "video/drawing_context.hpp"
-#include "lisp/list_iterator.hpp"
-#include "log.hpp"
-#include "scripting/level_time.hpp"
-#include "scripting/squirrel_util.hpp"
+#include "supertux/sector.hpp"
EndSequence::EndSequence()
-: isrunning(false), isdone(false), tux_may_walk(true)
+ : isrunning(false), isdone(false), tux_may_walk(true)
{
end_sequence_controller = 0;
}
return !tux_may_walk;
}
- bool
+bool
EndSequence::is_done()
{
return isdone;
EndSequence::stopping()
{
}
+
+/* EOF */
-// $Id$
-//
// SuperTux - End Sequence
// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __ENDSEQUENCE_H__
-#define __ENDSEQUENCE_H__
+#ifndef HEADER_SUPERTUX_OBJECT_ENDSEQUENCE_HPP
+#define HEADER_SUPERTUX_OBJECT_ENDSEQUENCE_HPP
-#include <memory>
-#include "game_object.hpp"
-#include "timer.hpp"
-#include "lisp/lisp.hpp"
#include "control/codecontroller.hpp"
+#include "supertux/game_object.hpp"
class EndSequence : public GameObject
{
public:
- EndSequence();
- virtual ~EndSequence();
+ EndSequence();
+ virtual ~EndSequence();
- virtual void update(float elapsed_time);
- virtual void draw(DrawingContext& context);
+ virtual void update(float elapsed_time);
+ virtual void draw(DrawingContext& context);
- void start(); /**< play EndSequence */
- void stop_tux(); /**< called when Tux has reached his final position */
- void stop(); /**< stop playing EndSequence, mark it as done playing */
- bool is_tux_stopped(); /**< returns true if Tux has reached his final position */
- bool is_done(); /**< returns true if EndSequence has finished playing */
+ void start(); /**< play EndSequence */
+ void stop_tux(); /**< called when Tux has reached his final position */
+ void stop(); /**< stop playing EndSequence, mark it as done playing */
+ bool is_tux_stopped(); /**< returns true if Tux has reached his final position */
+ bool is_done(); /**< returns true if EndSequence has finished playing */
protected:
- virtual void starting(); /**< called when EndSequence starts */
- virtual void running(float elapsed_time); /**< called while the EndSequence is running */
- virtual void stopping(); /**< called when EndSequence stops */
-
- bool isrunning; /**< true while EndSequence plays */
- bool isdone; /**< true if EndSequence has finished playing */
- bool tux_may_walk; /**< true while tux is allowed to walk */
- CodeController* end_sequence_controller;
-
+ virtual void starting(); /**< called when EndSequence starts */
+ virtual void running(float elapsed_time); /**< called while the EndSequence is running */
+ virtual void stopping(); /**< called when EndSequence stops */
+
+ bool isrunning; /**< true while EndSequence plays */
+ bool isdone; /**< true if EndSequence has finished playing */
+ bool tux_may_walk; /**< true while tux is allowed to walk */
+ CodeController* end_sequence_controller;
+
+private:
+ EndSequence(const EndSequence&);
+ EndSequence& operator=(const EndSequence&);
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux - End Sequence: Tux walks right
// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#include "object/endsequence_fireworks.hpp"
-#include <config.h>
-#include "endsequence_fireworks.hpp"
-#include "sector.hpp"
-#include "mainloop.hpp"
-#include "object/player.hpp"
#include "object/fireworks.hpp"
+#include "supertux/mainloop.hpp"
+#include "supertux/sector.hpp"
EndSequenceFireworks::EndSequenceFireworks()
-: EndSequence()
+ : EndSequence()
{
}
EndSequenceFireworks::starting()
{
EndSequence::starting();
- endsequence_timer.start(7.3f * main_loop->get_speed());
+ endsequence_timer.start(7.3f * g_main_loop->get_speed());
Sector::current()->add_object(new Fireworks());
}
{
EndSequence::stopping();
}
+
+/* EOF */
-// $Id$
-//
// SuperTux - End Sequence: Tux walks right
// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __ENDSEQUENCE_FIREWORKS_H__
-#define __ENDSEQUENCE_FIREWORKS_H__
+#ifndef HEADER_SUPERTUX_OBJECT_ENDSEQUENCE_FIREWORKS_HPP
+#define HEADER_SUPERTUX_OBJECT_ENDSEQUENCE_FIREWORKS_HPP
-#include <memory>
#include "object/endsequence.hpp"
-#include "timer.hpp"
+#include "supertux/timer.hpp"
class EndSequenceFireworks : public EndSequence
{
public:
- EndSequenceFireworks();
- virtual ~EndSequenceFireworks();
- virtual void draw(DrawingContext& context);
+ EndSequenceFireworks();
+ virtual ~EndSequenceFireworks();
+ virtual void draw(DrawingContext& context);
protected:
- virtual void starting(); /**< called when EndSequence starts */
- virtual void running(float elapsed_time); /**< called while the EndSequence is running */
- virtual void stopping(); /**< called when EndSequence stops */
+ virtual void starting(); /**< called when EndSequence starts */
+ virtual void running(float elapsed_time); /**< called while the EndSequence is running */
+ virtual void stopping(); /**< called when EndSequence stops */
- Timer endsequence_timer;
+ Timer endsequence_timer;
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux - End Sequence: Tux walks right
// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <config.h>
-#include "endsequence_walkleft.hpp"
-#include "sector.hpp"
-#include "mainloop.hpp"
+#include "object/endsequence_walkleft.hpp"
#include "object/player.hpp"
+#include "supertux/mainloop.hpp"
+#include "supertux/sector.hpp"
EndSequenceWalkLeft::EndSequenceWalkLeft()
-: EndSequence()
+ : EndSequence()
{
}
{
EndSequence::starting();
last_x_pos = -1;
- endsequence_timer.start(7.3f * main_loop->get_speed());
+ endsequence_timer.start(7.3f * g_main_loop->get_speed());
}
void
{
EndSequence::stopping();
}
+
+/* EOF */
-// $Id$
-//
// SuperTux - End Sequence: Tux walks right
// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __ENDSEQUENCE_WALKLEFT_H__
-#define __ENDSEQUENCE_WALKLEFT_H__
+#ifndef HEADER_SUPERTUX_OBJECT_ENDSEQUENCE_WALKLEFT_HPP
+#define HEADER_SUPERTUX_OBJECT_ENDSEQUENCE_WALKLEFT_HPP
-#include <memory>
#include "object/endsequence.hpp"
-#include "timer.hpp"
+#include "supertux/timer.hpp"
class EndSequenceWalkLeft : public EndSequence
{
public:
- EndSequenceWalkLeft();
- virtual ~EndSequenceWalkLeft();
- virtual void draw(DrawingContext& context);
+ EndSequenceWalkLeft();
+ virtual ~EndSequenceWalkLeft();
+ virtual void draw(DrawingContext& context);
protected:
- virtual void starting(); /**< called when EndSequence starts */
- virtual void running(float elapsed_time); /**< called while the EndSequence is running */
- virtual void stopping(); /**< called when EndSequence stops */
+ virtual void starting(); /**< called when EndSequence starts */
+ virtual void running(float elapsed_time); /**< called while the EndSequence is running */
+ virtual void stopping(); /**< called when EndSequence stops */
- float last_x_pos;
- Timer endsequence_timer;
+ float last_x_pos;
+ Timer endsequence_timer;
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux - End Sequence: Tux walks right
// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <config.h>
-#include "endsequence_walkright.hpp"
-#include "sector.hpp"
-#include "mainloop.hpp"
+#include "object/endsequence_walkright.hpp"
#include "object/player.hpp"
+#include "supertux/mainloop.hpp"
+#include "supertux/sector.hpp"
EndSequenceWalkRight::EndSequenceWalkRight()
-: EndSequence()
+ : EndSequence()
{
}
{
EndSequence::starting();
last_x_pos = -1;
- endsequence_timer.start(7.3f * main_loop->get_speed());
+ endsequence_timer.start(7.3f * g_main_loop->get_speed());
}
void
{
EndSequence::stopping();
}
+
+/* EOF */
-// $Id$
-//
// SuperTux - End Sequence: Tux walks right
// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __ENDSEQUENCE_WALKRIGHT_H__
-#define __ENDSEQUENCE_WALKRIGHT_H__
+#ifndef HEADER_SUPERTUX_OBJECT_ENDSEQUENCE_WALKRIGHT_HPP
+#define HEADER_SUPERTUX_OBJECT_ENDSEQUENCE_WALKRIGHT_HPP
-#include <memory>
#include "object/endsequence.hpp"
-#include "timer.hpp"
+#include "supertux/timer.hpp"
class EndSequenceWalkRight : public EndSequence
{
public:
- EndSequenceWalkRight();
- virtual ~EndSequenceWalkRight();
- virtual void draw(DrawingContext& context);
+ EndSequenceWalkRight();
+ virtual ~EndSequenceWalkRight();
+ virtual void draw(DrawingContext& context);
protected:
- virtual void starting(); /**< called when EndSequence starts */
- virtual void running(float elapsed_time); /**< called while the EndSequence is running */
- virtual void stopping(); /**< called when EndSequence stops */
+ virtual void starting(); /**< called when EndSequence starts */
+ virtual void running(float elapsed_time); /**< called while the EndSequence is running */
+ virtual void stopping(); /**< called when EndSequence stops */
- float last_x_pos;
- Timer endsequence_timer;
+ float last_x_pos;
+ Timer endsequence_timer;
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux -- Explosion object
// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "explosion.hpp"
+#include "object/explosion.hpp"
+#include "audio/sound_manager.hpp"
#include "badguy/badguy.hpp"
+#include "math/random_generator.hpp"
+#include "object/player.hpp"
#include "object/sprite_particle.hpp"
-#include "random_generator.hpp"
-#include "object_factory.hpp"
-#include "audio/sound_manager.hpp"
-#include "sector.hpp"
+#include "supertux/object_factory.hpp"
+#include "supertux/sector.hpp"
#include <math.h>
Explosion::Explosion(const Vector& pos)
- : MovingSprite(pos, "images/objects/explosion/explosion.sprite", LAYER_OBJECTS+40, COLGROUP_TOUCHABLE), state(STATE_WAITING)
+ : MovingSprite(pos, "images/objects/explosion/explosion.sprite", LAYER_OBJECTS+40, COLGROUP_TOUCHABLE), state(STATE_WAITING)
{
sound_manager->preload("sounds/explosion.wav");
set_pos(get_pos() - (get_bbox().get_middle() - get_pos()));
}
-Explosion::Explosion(const lisp::Lisp& reader)
- : MovingSprite(reader, "images/objects/explosion/explosion.sprite", LAYER_OBJECTS+40, COLGROUP_TOUCHABLE), state(STATE_WAITING)
+Explosion::Explosion(const Reader& reader)
+ : MovingSprite(reader, "images/objects/explosion/explosion.sprite", LAYER_OBJECTS+40, COLGROUP_TOUCHABLE), state(STATE_WAITING)
{
sound_manager->preload("sounds/explosion.wav");
}
sound_manager->play("sounds/explosion.wav", get_pos());
if (0)
- {
- // spawn some particles
- // TODO: provide convenience function in MovingSprite or MovingObject?
- for (int i = 0; i < 100; i++) {
- Vector ppos = bbox.get_middle();
- float angle = systemRandom.randf(-M_PI_2, M_PI_2);
- float velocity = systemRandom.randf(450, 900);
- float vx = sin(angle)*velocity;
- float vy = -cos(angle)*velocity;
- Vector pspeed = Vector(vx, vy);
- Vector paccel = Vector(0, 1000);
- Sector::current()->add_object(new SpriteParticle("images/objects/particles/explosion.sprite", "default", ppos, ANCHOR_MIDDLE, pspeed, paccel, LAYER_OBJECTS-1));
- }
+ {
+ // spawn some particles
+ // TODO: provide convenience function in MovingSprite or MovingObject?
+ for (int i = 0; i < 100; i++) {
+ Vector ppos = bbox.get_middle();
+ float angle = systemRandom.randf(-M_PI_2, M_PI_2);
+ float velocity = systemRandom.randf(450, 900);
+ float vx = sin(angle)*velocity;
+ float vy = -cos(angle)*velocity;
+ Vector pspeed = Vector(vx, vy);
+ Vector paccel = Vector(0, 1000);
+ Sector::current()->add_object(new SpriteParticle("images/objects/particles/explosion.sprite", "default", ppos, ANCHOR_MIDDLE, pspeed, paccel, LAYER_OBJECTS-1));
}
+ }
}
void
IMPLEMENT_FACTORY(Explosion, "explosion");
+/* EOF */
-// $Id$
-//
// SuperTux -- Explosion object
// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __EXPLOSION_H__
-#define __EXPLOSION_H__
+#ifndef HEADER_SUPERTUX_OBJECT_EXPLOSION_HPP
+#define HEADER_SUPERTUX_OBJECT_EXPLOSION_HPP
-#include "moving_sprite.hpp"
+#include "object/moving_sprite.hpp"
/**
* Just your average explosion - goes boom, hurts Tux
* Create new Explosion centered(!) at @c pos
*/
Explosion(const Vector& pos);
- Explosion(const lisp::Lisp& reader);
+ Explosion(const Reader& reader);
void update(float elapsed_time);
HitResponse collision(GameObject& other, const CollisionHit& hit);
#endif
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Ondrej Hosek <ondra.hosek@gmail.com>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <config.h>
+#include "object/falling_coin.hpp"
-#include "falling_coin.hpp"
-#include "player.hpp"
#include "sprite/sprite_manager.hpp"
-#include "resources.hpp"
-#include "main.hpp"
+#include "supertux/main.hpp"
FallingCoin::FallingCoin(const Vector& start_position, const int vel_x)
{
FallingCoin::~FallingCoin()
{
- delete sprite;
}
void
if (pos.y > SCREEN_HEIGHT)
remove_me();
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Ondrej Hosek <ondra.hosek@gmail.com>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __FALLING_COIN_H__
-#define __FALLING_COIN_H__
+#ifndef HEADER_SUPERTUX_OBJECT_FALLING_COIN_HPP
+#define HEADER_SUPERTUX_OBJECT_FALLING_COIN_HPP
-#include "game_object.hpp"
-#include "math/vector.hpp"
#include "sprite/sprite.hpp"
-#include "video/drawing_context.hpp"
-#include "physic.hpp"
+#include "supertux/game_object.hpp"
+#include "supertux/physic.hpp"
-class FallingCoin : public GameObject, private UsesPhysic
+class FallingCoin : public GameObject
{
public:
FallingCoin(const Vector& start_position, const int x_vel);
void draw(DrawingContext& context);
void update(float elapsed_time);
+
private:
- Vector pos;
- Sprite* sprite;
+ Physic physic;
+ Vector pos;
+ std::auto_ptr<Sprite> sprite;
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "firefly.hpp"
+#include "object/firefly.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "player.hpp"
-#include "object_factory.hpp"
-#include "game_session.hpp"
-#include "sector.hpp"
-#include "random_generator.hpp"
+#include "math/random_generator.hpp"
+#include "object/player.hpp"
#include "object/sprite_particle.hpp"
-#include "lisp/writer.hpp"
+#include "supertux/game_session.hpp"
+#include "supertux/object_factory.hpp"
+#include "supertux/sector.hpp"
#include <math.h>
-Firefly::Firefly(const lisp::Lisp& lisp)
- : MovingSprite(lisp, "images/objects/resetpoints/default-resetpoint.sprite", LAYER_TILES, COLGROUP_TOUCHABLE), activated(false)
+Firefly::Firefly(const Reader& lisp)
+ : MovingSprite(lisp, "images/objects/resetpoints/default-resetpoint.sprite", LAYER_TILES, COLGROUP_TOUCHABLE), activated(false)
{
initial_position = get_pos();
if( !lisp.get( "sprite", sprite_name ) ){
}
}
-void
-Firefly::write(lisp::Writer& writer)
-{
- writer.start_list("firefly");
- writer.write("x", bbox.p1.x);
- writer.write("y", bbox.p1.y);
- writer.end_list("firefly");
-}
-
HitResponse
Firefly::collision(GameObject& other, const CollisionHit& )
{
Player* player = dynamic_cast<Player*> (&other);
if(player) {
activated = true;
-// spawn some particles
-// TODO: provide convenience function in MovingSprite or MovingObject?
- for (int i = 0; i < 5; i++) {
- Vector ppos = bbox.get_middle();
- float angle = systemRandom.randf(-M_PI_2, M_PI_2);
- float velocity = systemRandom.randf(450, 900);
- float vx = sin(angle)*velocity;
- float vy = -cos(angle)*velocity;
- Vector pspeed = Vector(vx, vy);
- Vector paccel = Vector(0, 1000);
- Sector::current()->add_object(new SpriteParticle("images/objects/particles/reset.sprite", "default", ppos, ANCHOR_MIDDLE, pspeed, paccel, LAYER_OBJECTS-1));
- }
+ // spawn some particles
+ // TODO: provide convenience function in MovingSprite or MovingObject?
+ for (int i = 0; i < 5; i++) {
+ Vector ppos = bbox.get_middle();
+ float angle = systemRandom.randf(-M_PI_2, M_PI_2);
+ float velocity = systemRandom.randf(450, 900);
+ float vx = sin(angle)*velocity;
+ float vy = -cos(angle)*velocity;
+ Vector pspeed = Vector(vx, vy);
+ Vector paccel = Vector(0, 1000);
+ Sector::current()->add_object(new SpriteParticle("images/objects/particles/reset.sprite", "default", ppos, ANCHOR_MIDDLE, pspeed, paccel, LAYER_OBJECTS-1));
+ }
// TODO play sound
sprite->set_action("ringing");
GameSession::current()->set_reset_point(Sector::current()->get_name(),
- initial_position);
+ initial_position);
}
return ABORT_MOVE;
}
IMPLEMENT_FACTORY(Firefly, "firefly");
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __FIREFLY_H__
-#define __FIREFLY_H__
+#ifndef HEADER_SUPERTUX_OBJECT_FIREFLY_HPP
+#define HEADER_SUPERTUX_OBJECT_FIREFLY_HPP
#include "object/moving_sprite.hpp"
-#include "serializable.hpp"
/**
* A Firefly: When tux touches it, it begins buzzing and you will respawn at this
* position.
*/
-class Firefly : public MovingSprite, public Serializable
+class Firefly : public MovingSprite
{
public:
- Firefly(const lisp::Lisp& lisp);
- virtual Firefly* clone() const { return new Firefly(*this); }
+ Firefly(const Reader& lisp);
- void write(lisp::Writer& writer);
HitResponse collision(GameObject& other, const CollisionHit& hit);
private:
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "fireworks.hpp"
-#include "resources.hpp"
-#include "sector.hpp"
-#include "camera.hpp"
-#include "particles.hpp"
-#include "main.hpp"
-#include "video/drawing_context.hpp"
#include "audio/sound_manager.hpp"
-#include "random_generator.hpp"
+#include "math/random_generator.hpp"
+#include "object/camera.hpp"
+#include "object/fireworks.hpp"
+#include "object/particles.hpp"
+#include "supertux/main.hpp"
+#include "supertux/sector.hpp"
+#include "video/drawing_context.hpp"
Fireworks::Fireworks()
{
void
Fireworks::update(float )
{
- if(timer.check()) {
- Sector* sector = Sector::current();
- Vector pos = sector->camera->get_translation();
- pos += Vector(systemRandom.randf(SCREEN_WIDTH),
- systemRandom.randf(SCREEN_HEIGHT/2));
+ if(timer.check()) {
+ Sector* sector = Sector::current();
+ Vector pos = sector->camera->get_translation();
+ pos += Vector(systemRandom.randf(SCREEN_WIDTH),
+ systemRandom.randf(SCREEN_HEIGHT/2));
- float red = systemRandom.randf(1.0);
- float green = systemRandom.randf(1.0);
- //float red = 0.7;
- //float green = 0.9;
- (void) red;
- (void) green;
- sector->add_object(new Particles(pos, 0, 360, Vector(140, 140),
- Vector(0, 0), 45, Color(red, green, 0), 3, 1.3f,
- LAYER_FOREGROUND1+1));
- sound_manager->play("sounds/fireworks.wav");
- timer.start(systemRandom.randf(1.0, 1.5));
- }
+ float red = systemRandom.randf(1.0);
+ float green = systemRandom.randf(1.0);
+ //float red = 0.7;
+ //float green = 0.9;
+ (void) red;
+ (void) green;
+ sector->add_object(new Particles(pos, 0, 360, Vector(140, 140),
+ Vector(0, 0), 45, Color(red, green, 0), 3, 1.3f,
+ LAYER_FOREGROUND1+1));
+ sound_manager->play("sounds/fireworks.wav");
+ timer.start(systemRandom.randf(1.0, 1.5));
+ }
}
void
Fireworks::draw(DrawingContext& )
{
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#ifndef __FIREWORKS_H__
-#define __FIREWORKS_H__
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "video/drawing_context.hpp"
-#include "game_object.hpp"
-#include "timer.hpp"
+#ifndef HEADER_SUPERTUX_OBJECT_FIREWORKS_HPP
+#define HEADER_SUPERTUX_OBJECT_FIREWORKS_HPP
class Fireworks : public GameObject
{
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <stdexcept>
-#include "resources.hpp"
-#include "main.hpp"
-#include "math/rect.hpp"
-#include "sprite/sprite_manager.hpp"
+#include "object/floating_image.hpp"
#include "sprite/sprite.hpp"
-#include "video/drawing_context.hpp"
-#include "lisp/lisp.hpp"
-#include "floating_image.hpp"
-
-
-FloatingImage::FloatingImage(const std::string& spritefile)
- : layer(LAYER_FOREGROUND1 + 1), visible(false), anchor(ANCHOR_MIDDLE), fading(0), fadetime(0)
+#include "sprite/sprite_manager.hpp"
+#include "supertux/main.hpp"
+
+FloatingImage::FloatingImage(const std::string& spritefile) :
+ layer(LAYER_FOREGROUND1 + 1),
+ visible(false),
+ anchor(ANCHOR_MIDDLE),
+ fading(0),
+ fadetime(0)
{
- sprite.reset(sprite_manager->create(spritefile));
+ sprite = sprite_manager->create(spritefile);
}
FloatingImage::~FloatingImage()
}
}
-// (void) elapsed_time;
+ // (void) elapsed_time;
}
void
fading = -fadetime;
}
-
void
FloatingImage::draw(DrawingContext& context)
{
}
Vector spos = pos + get_anchor_pos(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT),
- sprite->get_width(), sprite->get_height(), anchor);
+ sprite->get_width(), sprite->get_height(), anchor);
sprite->draw(context, spos, layer);
context.pop_transform();
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __FLOATING_IMAGE_H__
-#define __FLOATING_IMAGE_H__
+#ifndef HEADER_SUPERTUX_OBJECT_FLOATING_IMAGE_HPP
+#define HEADER_SUPERTUX_OBJECT_FLOATING_IMAGE_HPP
-#include "game_object.hpp"
-#include "math/vector.hpp"
-#include "anchor_point.hpp"
+#include "object/anchor_point.hpp"
+#include "supertux/game_object.hpp"
#include <memory>
class Sprite;
};
#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include "object/floating_text.hpp"
+
+#include <stdio.h>
+
+#include "supertux/resources.hpp"
+#include "video/drawing_context.hpp"
+
+FloatingText::FloatingText(const Vector& pos, const std::string& text_)
+ : position(pos), text(text_)
+{
+ timer.start(.1f);
+ position.x -= text.size() * 8;
+}
+
+FloatingText::FloatingText(const Vector& pos, int score)
+ : position(pos)
+{
+ timer.start(.1f);
+
+ // turn int into a string
+ char str[10];
+ snprintf(str, 10, "%d", score);
+ text = str;
+
+ position.x -= text.size() * 8;
+}
+
+void
+FloatingText::update(float elapsed_time)
+{
+ position.y -= 1.4 * elapsed_time;
+
+ if(timer.check())
+ remove_me();
+}
+
+#define FADING_TIME .350
+
+void
+FloatingText::draw(DrawingContext& context)
+{
+ // make an alpha animation when disappearing
+ int alpha;
+ if(timer.get_timeleft() < FADING_TIME)
+ alpha = int(timer.get_timeleft() * 255 / FADING_TIME);
+ else
+ alpha = 255;
+
+ context.push_transform();
+ context.set_alpha(alpha);
+
+ context.draw_text(normal_font, text, position, ALIGN_LEFT, LAYER_OBJECTS+1, FloatingText::text_color);
+
+ context.pop_transform();
+}
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_OBJECT_FLOATING_TEXT_HPP
+#define HEADER_SUPERTUX_OBJECT_FLOATING_TEXT_HPP
+
+#include <memory>
+
+#include "math/vector.hpp"
+#include "supertux/game_object.hpp"
+#include "supertux/timer.hpp"
+#include "video/color.hpp"
+
+class Sprite;
+
+class FloatingText : public GameObject
+{
+ static Color text_color;
+public:
+ FloatingText(const Vector& pos, const std::string& text_);
+ FloatingText(const Vector& pos, int s); // use this for score, for instance
+
+ virtual void update(float elapsed_time);
+ virtual void draw(DrawingContext& context);
+
+private:
+ Vector position;
+ std::string text;
+ Timer timer;
+};
+
+#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <math.h>
-#include <assert.h>
-#include "flower.hpp"
-#include "resources.hpp"
-#include "camera.hpp"
-#include "sector.hpp"
-#include "player.hpp"
#include "audio/sound_manager.hpp"
+#include "object/flower.hpp"
+#include "object/player.hpp"
#include "sprite/sprite_manager.hpp"
-Flower::Flower(BonusType _type)
- : type(_type)
+Flower::Flower(BonusType _type) :
+ type(_type)
{
bbox.set_size(32, 32);
Flower::~Flower()
{
- delete sprite;
}
void
remove_me();
return ABORT_MOVE;
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __FLOWER_H__
-#define __FLOWER_H__
+#ifndef HEADER_SUPERTUX_OBJECT_FLOWER_HPP
+#define HEADER_SUPERTUX_OBJECT_FLOWER_HPP
-#include "moving_object.hpp"
#include "sprite/sprite.hpp"
-#include "player_status.hpp"
+#include "supertux/moving_object.hpp"
+#include "supertux/player_status.hpp"
class Flower : public MovingObject
{
private:
BonusType type;
- Sprite* sprite;
+ std::auto_ptr<Sprite> sprite;
+
+private:
+ Flower(const Flower&);
+ Flower& operator=(const Flower&);
};
#endif
+
+/* EOF */
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
-
-#include <algorithm>
-#include <iostream>
-#include <cmath>
-
-#include "tile.hpp"
-#include "tile_manager.hpp"
-#include "game_session.hpp"
-#include "gameobjs.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "sprite/sprite.hpp"
-#include "resources.hpp"
-#include "sector.hpp"
-#include "tilemap.hpp"
-#include "video/drawing_context.hpp"
-#include "camera.hpp"
-#include "main.hpp"
-#include "random_generator.hpp"
-
-/** this controls the time over which a bouncy coin fades */
-static const float FADE_TIME = .2f;
-/** this is the total life time of a bouncy coin */
-static const float LIFE_TIME = .5f;
-
-BouncyCoin::BouncyCoin(const Vector& pos, bool emerge)
- : position(pos), emerge_distance(0)
-{
- timer.start(LIFE_TIME);
- sprite = sprite_manager->create("images/objects/coin/coin.sprite");
-
- if(emerge) {
- emerge_distance = sprite->get_height();
- }
-}
-
-BouncyCoin::~BouncyCoin()
-{
- delete sprite;
-}
-
-void
-BouncyCoin::update(float elapsed_time)
-{
- float dist = -200 * elapsed_time;
- position.y += dist;
- emerge_distance += dist;
-
- if(timer.check())
- remove_me();
-}
-
-void
-BouncyCoin::draw(DrawingContext& context)
-{
- float time_left = timer.get_timeleft();
- bool fading = time_left < FADE_TIME;
- if(fading) {
- float alpha = time_left/FADE_TIME;
- context.push_transform();
- context.set_alpha(alpha);
- }
-
- int layer;
- if(emerge_distance > 0) {
- layer = LAYER_OBJECTS - 5;
- } else {
- layer = LAYER_OBJECTS + 5;
- }
- sprite->draw(context, position, layer);
-
- if(fading) {
- context.pop_transform();
- }
-}
-
-//---------------------------------------------------------------------------
-
-BrokenBrick::BrokenBrick(Sprite* nsprite,
- const Vector& pos, const Vector& nmovement)
- : sprite(new Sprite(*nsprite)), position(pos), movement(nmovement)
-{
- timer.start(.2f);
-}
-
-BrokenBrick::~BrokenBrick()
-{
- delete sprite;
-}
-
-void
-BrokenBrick::update(float elapsed_time)
-{
- position += movement * elapsed_time;
-
- if (timer.check())
- remove_me();
-}
-
-void
-BrokenBrick::draw(DrawingContext& context)
-{
- sprite->draw_part(context,
- Vector(systemRandom.rand(16), systemRandom.rand(16)), Vector(16, 16),
- position, LAYER_OBJECTS + 1);
-}
-
-//---------------------------------------------------------------------------
-
-FloatingText::FloatingText(const Vector& pos, const std::string& text_)
- : position(pos), text(text_)
-{
- timer.start(.1f);
- position.x -= text.size() * 8;
-}
-
-FloatingText::FloatingText(const Vector& pos, int score)
- : position(pos)
-{
- timer.start(.1f);
-
- // turn int into a string
- char str[10];
- snprintf(str, 10, "%d", score);
- text = str;
-
- position.x -= text.size() * 8;
-}
-
-void
-FloatingText::update(float elapsed_time)
-{
- position.y -= 1.4 * elapsed_time;
-
- if(timer.check())
- remove_me();
-}
-
-#define FADING_TIME .350
-
-void
-FloatingText::draw(DrawingContext& context)
-{
- // make an alpha animation when disappearing
- int alpha;
- if(timer.get_timeleft() < FADING_TIME)
- alpha = int(timer.get_timeleft() * 255 / FADING_TIME);
- else
- alpha = 255;
-
- context.push_transform();
- context.set_alpha(alpha);
-
- context.draw_text(normal_font, text, position, ALIGN_LEFT, LAYER_OBJECTS+1, FloatingText::text_color);
-
- context.pop_transform();
-}
-
-Sprite *img_smoke_cloud = 0;
-
-SmokeCloud::SmokeCloud(const Vector& pos)
- : position(pos)
-{
- timer.start(.3f);
- sprite = sprite_manager->create("images/objects/particles/stomp.sprite");
-}
-
-SmokeCloud::~SmokeCloud()
-{
- delete sprite;
-}
-
-void
-SmokeCloud::update(float elapsed_time)
-{
- position.y -= 120 * elapsed_time;
-
- if(timer.check())
- remove_me();
-}
-
-void
-SmokeCloud::draw(DrawingContext& context)
-{
- sprite->draw(context, position, LAYER_OBJECTS+1);
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#ifndef SUPERTUX_GAMEOBJS_H
-#define SUPERTUX_GAMEOBJS_H
-
-#include "video/surface.hpp"
-#include "timer.hpp"
-#include "game_object.hpp"
-#include "moving_object.hpp"
-#include "serializable.hpp"
-#include "video/color.hpp"
-
-/* Bounciness of distros: */
-#define NO_BOUNCE 0
-#define BOUNCE 1
-
-class Sprite;
-
-class BouncyCoin : public GameObject
-{
-public:
- BouncyCoin(const Vector& pos, bool emerge=false);
- ~BouncyCoin();
- virtual void update(float elapsed_time);
- virtual void draw(DrawingContext& context);
-
-private:
- Sprite* sprite;
- Vector position;
- Timer timer;
- float emerge_distance;
-};
-
-class BrokenBrick : public GameObject
-{
-public:
- BrokenBrick(Sprite* sprite, const Vector& pos, const Vector& movement);
- ~BrokenBrick();
-
- virtual void update(float elapsed_time);
- virtual void draw(DrawingContext& context);
-
-private:
- Timer timer;
- Sprite* sprite;
- Vector position;
- Vector movement;
-};
-
-class FloatingText : public GameObject
-{
- static Color text_color;
-public:
- FloatingText(const Vector& pos, const std::string& text_);
- FloatingText(const Vector& pos, int s); // use this for score, for instance
-
- virtual void update(float elapsed_time);
- virtual void draw(DrawingContext& context);
-
-private:
- Vector position;
- std::string text;
- Timer timer;
-};
-
-class SmokeCloud : public GameObject
-{
-public:
- SmokeCloud(const Vector& pos);
- ~SmokeCloud();
-
- virtual void update(float elapsed_time);
- virtual void draw(DrawingContext& context);
-
-private:
- Sprite* sprite;
- Timer timer;
- Vector position;
-};
-
-#endif
-
-/* Local Variables: */
-/* mode:c++ */
-/* End: */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <stdexcept>
-#include "gradient.hpp"
-#include "camera.hpp"
-#include "video/drawing_context.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
-#include "resources.hpp"
-#include "main.hpp"
-#include "log.hpp"
+#include "object/gradient.hpp"
+#include "supertux/object_factory.hpp"
+#include "util/reader.hpp"
-Gradient::Gradient()
- : layer(LAYER_BACKGROUND0)
+Gradient::Gradient() :
+ layer(LAYER_BACKGROUND0)
{
}
-Gradient::Gradient(const lisp::Lisp& reader)
- : layer(LAYER_BACKGROUND0)
+Gradient::Gradient(const Reader& reader) :
+ layer(LAYER_BACKGROUND0)
{
reader.get("layer", layer);
std::vector<float> bkgd_top_color, bkgd_bottom_color;
}
void
-Gradient::write(lisp::Writer& writer)
-{
- writer.start_list("gradient");
-
- std::vector<float> bkgd_top_color, bkgd_bottom_color;
- bkgd_top_color.push_back(gradient_top.red);
- bkgd_top_color.push_back(gradient_top.green);
- bkgd_top_color.push_back(gradient_top.blue);
- bkgd_bottom_color.push_back(gradient_bottom.red);
- bkgd_bottom_color.push_back(gradient_bottom.green);
- bkgd_bottom_color.push_back(gradient_bottom.blue);
- writer.write("top_color", bkgd_top_color);
- writer.write("bottom_color", bkgd_bottom_color);
-
- writer.write("layer", layer);
-
- writer.end_list("gradient");
-}
-
-void
Gradient::update(float)
{
}
gradient_bottom = bottom;
if (gradient_top.red > 1.0 || gradient_top.green > 1.0
- || gradient_top.blue > 1.0 || gradient_top.alpha > 1.0)
+ || gradient_top.blue > 1.0 || gradient_top.alpha > 1.0)
log_warning << "top gradient color has values above 1.0" << std::endl;
if (gradient_bottom.red > 1.0 || gradient_bottom.green > 1.0
- || gradient_bottom.blue > 1.0 || gradient_bottom.alpha > 1.0)
+ || gradient_bottom.blue > 1.0 || gradient_bottom.alpha > 1.0)
log_warning << "bottom gradient color has values above 1.0" << std::endl;
}
}
IMPLEMENT_FACTORY(Gradient, "gradient");
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef SUPERTUX_GRADIENT_H
-#define SUPERTUX_GRADIENT_H
+#ifndef HEADER_SUPERTUX_OBJECT_GRADIENT_HPP
+#define HEADER_SUPERTUX_OBJECT_GRADIENT_HPP
-#include <memory>
-#include "video/surface.hpp"
+#include "supertux/game_object.hpp"
+#include "util/reader_fwd.hpp"
#include "video/drawing_context.hpp"
-#include "game_object.hpp"
-#include "serializable.hpp"
class DisplayManager;
-namespace lisp {
-class Lisp;
-}
-
-class Gradient : public GameObject, public Serializable
+class Gradient : public GameObject
{
public:
Gradient();
- Gradient(const lisp::Lisp& reader);
+ Gradient(const Reader& reader);
virtual ~Gradient();
- virtual void write(lisp::Writer& writer);
-
void set_gradient(Color top, Color bottom);
Color get_gradient_top() const
};
#endif /*SUPERTUX_BACKGROUND_H*/
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <math.h>
-#include "growup.hpp"
-#include "resources.hpp"
-#include "camera.hpp"
-#include "sector.hpp"
-#include "player.hpp"
#include "audio/sound_manager.hpp"
+#include "object/growup.hpp"
+#include "object/player.hpp"
-GrowUp::GrowUp(Direction direction)
- : MovingSprite(Vector(0,0), "images/powerups/egg/egg.sprite", LAYER_OBJECTS, COLGROUP_MOVING)
+GrowUp::GrowUp(Direction direction) :
+ MovingSprite(Vector(0,0), "images/powerups/egg/egg.sprite", LAYER_OBJECTS, COLGROUP_MOVING)
{
physic.enable_gravity(true);
physic.set_velocity_x((direction == LEFT)?-100:100);
void
GrowUp::do_jump()
{
- physic.set_velocity_y(-300);
+ physic.set_velocity_y(-300);
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __GROWUP_H__
-#define __GROWUP_H__
+#ifndef HEADER_SUPERTUX_OBJECT_GROWUP_HPP
+#define HEADER_SUPERTUX_OBJECT_GROWUP_HPP
#include "object/moving_sprite.hpp"
-#include "physic.hpp"
-#include "direction.hpp"
+#include "supertux/direction.hpp"
+#include "supertux/physic.hpp"
-class GrowUp : public MovingSprite, private UsesPhysic
+class GrowUp : public MovingSprite
{
public:
GrowUp(Direction direction = RIGHT);
- virtual GrowUp* clone() const { return new GrowUp(*this); }
virtual void update(float elapsed_time);
virtual void collision_solid(const CollisionHit& hit);
virtual HitResponse collision(GameObject& other, const CollisionHit& hit);
void do_jump();
+
+private:
+ Physic physic;
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux - Hurting Platform
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
-#include <stdexcept>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "hurting_platform.hpp"
+#include "object/hurting_platform.hpp"
-#include "log.hpp"
-#include "player.hpp"
#include "badguy/badguy.hpp"
-#include "object_factory.hpp"
+#include "object/player.hpp"
+#include "supertux/object_factory.hpp"
-HurtingPlatform::HurtingPlatform(const lisp::Lisp& reader)
- : Platform(reader)
+HurtingPlatform::HurtingPlatform(const Reader& reader)
+ : Platform(reader)
{
set_group(COLGROUP_TOUCHABLE);
}
}
IMPLEMENT_FACTORY(HurtingPlatform, "hurting_platform");
+
+/* EOF */
-// $Id$
-//
// SuperTux - Hurting Platform
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __HURTING_PLATFORM_H__
-#define __HURTING_PLATFORM_H__
+#ifndef HEADER_SUPERTUX_OBJECT_HURTING_PLATFORM_HPP
+#define HEADER_SUPERTUX_OBJECT_HURTING_PLATFORM_HPP
-#include <memory>
#include "object/platform.hpp"
/**
class HurtingPlatform : public Platform
{
public:
- HurtingPlatform(const lisp::Lisp& reader);
- virtual HurtingPlatform* clone() const { return new HurtingPlatform(*this); }
+ HurtingPlatform(const Reader& reader);
virtual HitResponse collision(GameObject& other, const CollisionHit& hit);
};
#endif
+
+/* EOF */
-// $Id$
-//
// IceCrusher - A block to stand on, which can drop down to crush the player
// Copyright (C) 2008 Christoph Sommer <christoph.sommer@2008.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "icecrusher.hpp"
+#include "object/icecrusher.hpp"
-#include <stdexcept>
-#include "log.hpp"
-#include "video/drawing_context.hpp"
-#include "resources.hpp"
#include "badguy/badguy.hpp"
#include "sprite/sprite.hpp"
-#include "lisp/lisp.hpp"
-#include "object_factory.hpp"
-#include "sector.hpp"
+#include "object/player.hpp"
+#include "supertux/object_factory.hpp"
+#include "supertux/sector.hpp"
namespace {
- const float DROP_SPEED = 500;
- const float RECOVER_SPEED = 200;
+const float DROP_SPEED = 500;
+const float RECOVER_SPEED = 200;
}
-IceCrusher::IceCrusher(const lisp::Lisp& reader)
- : MovingSprite(reader, "images/creatures/icecrusher/icecrusher.sprite", LAYER_OBJECTS, COLGROUP_STATIC),
- state(IDLE), speed(Vector(0,0))
+IceCrusher::IceCrusher(const Reader& reader)
+ : MovingSprite(reader, "images/creatures/icecrusher/icecrusher.sprite", LAYER_OBJECTS, COLGROUP_STATIC),
+ state(IDLE), speed(Vector(0,0))
{
start_position = get_bbox().p1;
set_state(state, true);
}
-IceCrusher::IceCrusher(const IceCrusher& other)
- : MovingSprite(other),
- state(other.state), speed(other.speed)
-{
+/*
+ IceCrusher::IceCrusher(const IceCrusher& other)
+ : MovingSprite(other),
+ state(other.state), speed(other.speed)
+ {
start_position = get_bbox().p1;
set_state(state, true);
-}
-
+ }
+*/
void
IceCrusher::set_state(IceCrusherState state, bool force)
{
}
IMPLEMENT_FACTORY(IceCrusher, "icecrusher");
+
+/* EOF */
-// $Id$
-//
// IceCrusher - A block to stand on, which can drop down to crush the player
// Copyright (C) 2008 Christoph Sommer <christoph.sommer@2008.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef INCLUDED_ICECRUSHER_HPP
-#define INCLUDED_ICECRUSHER_HPP
+#ifndef HEADER_SUPERTUX_OBJECT_ICECRUSHER_HPP
+#define HEADER_SUPERTUX_OBJECT_ICECRUSHER_HPP
-#include <memory>
-#include <string>
#include "object/moving_sprite.hpp"
-#include "object/player.hpp"
+
+class Player;
/**
* This class is the base class for icecrushers that tux can stand on
*/
class IceCrusher : public MovingSprite
{
- public:
- IceCrusher(const lisp::Lisp& reader);
- IceCrusher(const IceCrusher& icecrusher);
- virtual IceCrusher* clone() const { return new IceCrusher(*this); }
-
- virtual HitResponse collision(GameObject& other, const CollisionHit& hit);
- virtual void collision_solid(const CollisionHit& hit);
- virtual void update(float elapsed_time);
-
- const Vector& get_speed() const
- {
- return speed;
- }
-
- protected:
- enum IceCrusherState {
- IDLE,
- CRUSHING,
- RECOVERING
- };
- IceCrusherState state;
- Vector start_position;
- Vector speed;
-
- Player* get_nearest_player();
- bool found_victim();
- void set_state(IceCrusherState state, bool force = false);
+public:
+ IceCrusher(const Reader& reader);
+ IceCrusher(const IceCrusher& icecrusher);
+
+ virtual HitResponse collision(GameObject& other, const CollisionHit& hit);
+ virtual void collision_solid(const CollisionHit& hit);
+ virtual void update(float elapsed_time);
+
+ const Vector& get_speed() const
+ {
+ return speed;
+ }
+
+protected:
+ enum IceCrusherState {
+ IDLE,
+ CRUSHING,
+ RECOVERING
+ };
+ IceCrusherState state;
+ Vector start_position;
+ Vector speed;
+
+ Player* get_nearest_player();
+ bool found_victim();
+ void set_state(IceCrusherState state, bool force = false);
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "infoblock.hpp"
+#include "object/infoblock.hpp"
-#include "game_session.hpp"
-#include "resources.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "object_factory.hpp"
-#include "lisp/lisp.hpp"
-#include "sector.hpp"
-#include "log.hpp"
#include "object/player.hpp"
-#include "main.hpp"
+#include "sprite/sprite_manager.hpp"
+#include "supertux/object_factory.hpp"
+#include "supertux/sector.hpp"
+#include "util/reader.hpp"
#include "video/drawing_context.hpp"
-#include "object/camera.hpp"
namespace {
- const float SCROLL_DELAY = 0.5;
- const float SCROLL_DISTANCE = 16;
- const float WIDTH = 400;
- const float HEIGHT = 200;
+const float SCROLL_DELAY = 0.5;
+const float SCROLL_DISTANCE = 16;
+const float WIDTH = 400;
+const float HEIGHT = 200;
}
-InfoBlock::InfoBlock(const lisp::Lisp& lisp)
- : Block(sprite_manager->create("images/objects/bonus_block/infoblock.sprite")), shown_pct(0), dest_pct(0)
+InfoBlock::InfoBlock(const Reader& lisp) :
+ Block(sprite_manager->create("images/objects/bonus_block/infoblock.sprite")),
+ shown_pct(0),
+ dest_pct(0)
{
Vector pos;
lisp.get("x", pos.x);
dest_pct = 0;
}
-IMPLEMENT_FACTORY(InfoBlock, "infoblock")
+IMPLEMENT_FACTORY(InfoBlock, "infoblock");
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __INFOBLOCK_H__
-#define __INFOBLOCK_H__
+#ifndef HEADER_SUPERTUX_OBJECT_INFOBLOCK_HPP
+#define HEADER_SUPERTUX_OBJECT_INFOBLOCK_HPP
-#include "block.hpp"
-//#include "object/ambient_sound.hpp"
-#include "textscroller.hpp"
+#include "object/block.hpp"
+#include "supertux/textscroller.hpp"
class InfoBlock : public Block
{
public:
- InfoBlock(const lisp::Lisp& lisp);
+ InfoBlock(const Reader& lisp);
virtual ~InfoBlock();
void update(float elapsed_time);
void draw(DrawingContext& context);
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "invisible_block.hpp"
-#include "resources.hpp"
-#include "sprite/sprite.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "video/drawing_context.hpp"
#include "audio/sound_manager.hpp"
-#include "object_factory.hpp"
+#include "object/invisible_block.hpp"
#include "object/player.hpp"
-#include "constants.hpp"
+#include "sprite/sprite.hpp"
+#include "sprite/sprite_manager.hpp"
+#include "supertux/constants.hpp"
-InvisibleBlock::InvisibleBlock(const Vector& pos)
- : Block(sprite_manager->create("images/objects/bonus_block/invisibleblock.sprite")), visible(false)
+InvisibleBlock::InvisibleBlock(const Vector& pos) :
+ Block(sprite_manager->create("images/objects/bonus_block/invisibleblock.sprite")),
+ visible(false)
{
bbox.set_pos(pos);
sound_manager->preload("sounds/brick.wav");
// if we're not visible, only register a collision if this will make us visible
Player* player = dynamic_cast<Player*> (&other);
if ((player)
- && (player->get_movement().y <= 0)
- && (player->get_bbox().get_top() > get_bbox().get_bottom() - SHIFT_DELTA)) {
+ && (player->get_movement().y <= 0)
+ && (player->get_bbox().get_top() > get_bbox().get_bottom() - SHIFT_DELTA)) {
return true;
}
}
//IMPLEMENT_FACTORY(InvisibleBlock, "invisible_block");
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __INVISIBLE_BLOCK_H__
-#define __INVISIBLE_BLOCK_H__
+#ifndef HEADER_SUPERTUX_OBJECT_INVISIBLE_BLOCK_HPP
+#define HEADER_SUPERTUX_OBJECT_INVISIBLE_BLOCK_HPP
-#include "block.hpp"
+#include "object/block.hpp"
class InvisibleBlock : public Block
{
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <config.h>
+#include "object/invisible_wall.hpp"
-#include "invisible_wall.hpp"
-#include "lisp/lisp.hpp"
-#include "object_factory.hpp"
-#include "sprite/sprite.hpp"
+#include "supertux/object_factory.hpp"
+#include "util/reader.hpp"
-InvisibleWall::InvisibleWall(const lisp::Lisp& lisp)
- : MovingSprite(lisp, "images/objects/invisible/invisible.sprite", LAYER_TILES, COLGROUP_STATIC), width(32), height(32)
+InvisibleWall::InvisibleWall(const Reader& lisp)
+ : MovingSprite(lisp, "images/objects/invisible/invisible.sprite", LAYER_TILES, COLGROUP_STATIC), width(32), height(32)
{
- lisp.get("width", width);
- lisp.get("height", height);
- bbox.set_size(width, height);
+ lisp.get("width", width);
+ lisp.get("height", height);
+ bbox.set_size(width, height);
}
HitResponse
}
IMPLEMENT_FACTORY(InvisibleWall, "invisible_wall");
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __INVISIBLE_WALL_H__
-#define __INVISIBLE_WALL_H__
+#ifndef HEADER_SUPERTUX_OBJECT_INVISIBLE_WALL_HPP
+#define HEADER_SUPERTUX_OBJECT_INVISIBLE_WALL_HPP
#include "object/moving_sprite.hpp"
-#include "lisp/lisp.hpp"
-#include "physic.hpp"
-#include "timer.hpp"
+#include "supertux/physic.hpp"
class Player;
/** A tile that starts falling down if tux stands to long on it */
-class InvisibleWall : public MovingSprite, private UsesPhysic
+class InvisibleWall : public MovingSprite
{
public:
- InvisibleWall(const lisp::Lisp& lisp);
- virtual InvisibleWall* clone() const { return new InvisibleWall(*this); }
+ InvisibleWall(const Reader& lisp);
HitResponse collision(GameObject& other, const CollisionHit& hit);
private:
+ Physic physic;
float width, height;
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux - Ispy
// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "ispy.hpp"
+#include "object/ispy.hpp"
-#include "player.hpp"
-#include "object_factory.hpp"
-#include "sector.hpp"
-#include "tile.hpp"
+#include "object/player.hpp"
#include "object/tilemap.hpp"
-#include "lisp/writer.hpp"
#include "sprite/sprite.hpp"
+#include "supertux/object_factory.hpp"
+#include "supertux/sector.hpp"
+#include "supertux/tile.hpp"
-Ispy::Ispy(const lisp::Lisp& reader)
- : MovingSprite(reader, "images/objects/ispy/ispy.sprite", LAYER_TILES+5, COLGROUP_DISABLED), state(ISPYSTATE_IDLE), dir(AUTO)
+Ispy::Ispy(const Reader& reader)
+ : MovingSprite(reader, "images/objects/ispy/ispy.sprite", LAYER_TILES+5, COLGROUP_DISABLED), state(ISPYSTATE_IDLE), dir(AUTO)
{
// read script to execute
reader.get("script", script);
sprite->set_action((dir == DOWN) ? "idle-down" : ((dir == LEFT) ? "idle-left" : "idle-right"));
}
-void
-Ispy::write(lisp::Writer& writer)
-{
- writer.start_list("ispy");
- writer.write("x", bbox.p1.x);
- writer.write("y", bbox.p1.y);
- writer.write("script", script);
- switch (dir)
- {
- case DOWN:
- writer.write("direction", "down"); break;
- case LEFT:
- writer.write("direction", "left"); break;
- case RIGHT:
- writer.write("direction", "right"); break;
- default: break;
- }
- writer.end_list("ispy");
-}
-
HitResponse
Ispy::collision(GameObject& , const CollisionHit& )
{
if (moving_object == ignore_object) continue;
if (!moving_object->is_valid()) continue;
if ((moving_object->get_group() == COLGROUP_MOVING)
- || (moving_object->get_group() == COLGROUP_MOVING_STATIC)
- || (moving_object->get_group() == COLGROUP_STATIC)) {
+ || (moving_object->get_group() == COLGROUP_MOVING_STATIC)
+ || (moving_object->get_group() == COLGROUP_STATIC)) {
if(intersects_line(moving_object->get_bbox(), line_start, line_end)) return false;
}
}
IMPLEMENT_FACTORY(Ispy, "ispy");
-
+/* EOF */
-// $Id$
-//
// SuperTux - Ispy
// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __OBJECT_ISPY_H__
-#define __OBJECT_ISPY_H__
+#ifndef HEADER_SUPERTUX_OBJECT_ISPY_HPP
+#define HEADER_SUPERTUX_OBJECT_ISPY_HPP
#include "object/moving_sprite.hpp"
-#include "serializable.hpp"
-#include "direction.hpp"
+#include "supertux/direction.hpp"
/**
* An Ispy: When it spots Tux, a script will run.
*/
-class Ispy : public MovingSprite, public Serializable
+class Ispy : public MovingSprite
{
public:
- Ispy(const lisp::Lisp& lisp);
+ Ispy(const Reader& lisp);
- void write(lisp::Writer& writer);
HitResponse collision(GameObject& other, const CollisionHit& hit);
virtual void update(float elapsed_time);
#endif
+/* EOF */
-// $Id$
-//
// SuperTux - Lantern
// Copyright (C) 2006 Wolfgang Becker <uafr@gmx.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "lantern.hpp"
+#include "object/lantern.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "object_factory.hpp"
-#include "badguy/willowisp.hpp"
-#include "badguy/treewillowisp.hpp"
#include "audio/sound_manager.hpp"
+#include "badguy/treewillowisp.hpp"
+#include "badguy/willowisp.hpp"
#include "sprite/sprite.hpp"
-#include "video/drawing_context.hpp"
+#include "sprite/sprite_manager.hpp"
+#include "supertux/object_factory.hpp"
-Lantern::Lantern(const lisp::Lisp& reader)
+Lantern::Lantern(const Reader& reader)
: Rock(reader, "images/objects/lantern/lantern.sprite"),
lightcolor(1.0f, 1.0f, 1.0f)
{
Lantern::~Lantern()
{
- delete lightsprite;
}
void
lightsprite->set_color(lightcolor);
//Turn lantern off if light is black
if(lightcolor.red == 0 && lightcolor.green == 0 && lightcolor.blue == 0){
- sprite->set_action("off");
+ sprite->set_action("off");
} else {
- sprite->set_action("normal");
- sprite->set_color(lightcolor);
+ sprite->set_action("normal");
+ sprite->set_color(lightcolor);
}
}
IMPLEMENT_FACTORY(Lantern, "lantern");
+/* EOF */
-// $Id$
-//
// SuperTux - Lantern
// Copyright (C) 2006 Wolfgang Becker <uafr@gmx.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __SUPERTUX_LANTERN_H__
-#define __SUPERTUX_LANTERN_H__
+#ifndef HEADER_SUPERTUX_OBJECT_LANTERN_HPP
+#define HEADER_SUPERTUX_OBJECT_LANTERN_HPP
-#include "object/moving_sprite.hpp"
#include "object/rock.hpp"
/**
{
public:
Lantern(const Vector& pos);
- Lantern(const lisp::Lisp& reader);
+ Lantern(const Reader& reader);
void draw(DrawingContext& context);
~Lantern();
private:
Color lightcolor;
- Sprite* lightsprite;
+ std::auto_ptr<Sprite> lightsprite;
void updateColor();
+
+private:
+ Lantern(const Lantern&);
+ Lantern& operator=(const Lantern&);
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "level_time.hpp"
+#include "object/level_time.hpp"
-#include "main.hpp"
-#include "resources.hpp"
-#include "sector.hpp"
-#include "gettext.hpp"
-#include "object_factory.hpp"
#include "object/player.hpp"
-#include "video/drawing_context.hpp"
-#include "lisp/list_iterator.hpp"
-#include "log.hpp"
#include "scripting/level_time.hpp"
#include "scripting/squirrel_util.hpp"
+#include "supertux/main.hpp"
+#include "supertux/object_factory.hpp"
+#include "supertux/resources.hpp"
+#include "supertux/sector.hpp"
+#include "util/reader.hpp"
+#include "video/drawing_context.hpp"
#include <math.h>
/** When to alert player they're low on time! */
static const float TIME_WARNING = 20;
-LevelTime::LevelTime(const lisp::Lisp& reader)
-: running(true), time_left(0)
+LevelTime::LevelTime(const Reader& reader) :
+ running(true),
+ time_left(0)
{
reader.get("name", name);
reader.get("time", time_left);
}
IMPLEMENT_FACTORY(LevelTime, "leveltime");
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_OBJECT_LEVEL_TIME_HPP
+#define HEADER_SUPERTUX_OBJECT_LEVEL_TIME_HPP
-#ifndef __LEVELTIME_H__
-#define __LEVELTIME_H__
+#include <memory>
-#include "game_object.hpp"
-#include "timer.hpp"
-#include "lisp/lisp.hpp"
-#include "video/surface.hpp"
-#include "script_interface.hpp"
+#include "supertux/game_object.hpp"
+#include "supertux/script_interface.hpp"
+#include "util/reader_fwd.hpp"
#include "video/color.hpp"
-#include <memory>
+class Surface;
-class LevelTime : public GameObject, public ScriptInterface
+class LevelTime : public GameObject,
+ public ScriptInterface
{
- static Color text_color;
+ static Color text_color;
public:
- LevelTime(const lisp::Lisp& reader);
+ LevelTime(const Reader& reader);
- virtual void expose(HSQUIRRELVM vm, SQInteger table_idx);
- virtual void unexpose(HSQUIRRELVM vm, SQInteger table_idx);
+ virtual void expose(HSQUIRRELVM vm, SQInteger table_idx);
+ virtual void unexpose(HSQUIRRELVM vm, SQInteger table_idx);
- void update(float elapsed_time);
- void draw(DrawingContext& context);
+ void update(float elapsed_time);
+ void draw(DrawingContext& context);
- /**
- * @name Scriptable Methods
- * @{
- */
+ /**
+ * @name Scriptable Methods
+ * @{
+ */
- /**
- * Resumes the countdown
- */
- void start();
+ /**
+ * Resumes the countdown
+ */
+ void start();
- /**
- * Pauses the countdown
- */
- void stop();
+ /**
+ * Pauses the countdown
+ */
+ void stop();
- /**
- * Returns the number of seconds left on the clock
- */
- float get_time();
+ /**
+ * Returns the number of seconds left on the clock
+ */
+ float get_time();
- /**
- * Changes the number of seconds left on the clock
- */
- void set_time(float time_left);
+ /**
+ * Changes the number of seconds left on the clock
+ */
+ void set_time(float time_left);
- /**
- * @}
- */
+ /**
+ * @}
+ */
private:
- std::auto_ptr<Surface> time_surface;
- bool running;
- float time_left;
+ std::auto_ptr<Surface> time_surface;
+ bool running;
+ float time_left;
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "light.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "resources.hpp"
-#include "video/drawing_context.hpp"
-#include "object_factory.hpp"
-#include "player.hpp"
-#include "sector.hpp"
+#include "object/light.hpp"
#include "sprite/sprite.hpp"
+#include "sprite/sprite_manager.hpp"
Light::Light(const Vector& center, const Color& color) : position(center), color(color)
{
Light::~Light()
{
- delete sprite;
}
void
context.pop_target();
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_OBJECT_LIGHT_HPP
+#define HEADER_SUPERTUX_OBJECT_LIGHT_HPP
-#ifndef __LIGHT_HPP__
-#define __LIGHT_HPP__
+#include <memory>
-#include "game_object.hpp"
-#include "lisp/lisp.hpp"
#include "math/vector.hpp"
+#include "supertux/game_object.hpp"
#include "video/color.hpp"
class Sprite;
protected:
Vector position;
Color color;
- Sprite* sprite;
+ std::auto_ptr<Sprite> sprite;
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux - MagicBlock
//
// Magic Blocks are tile-like game objects that are sensitive to
//
// Copyright (C) 2006 Wolfgang Becker <uafr@gmx.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
-#include <vector>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "object/camera.hpp"
-#include "magicblock.hpp"
-#include "object_factory.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "sector.hpp"
-#include "main.hpp"
+#include "object/magicblock.hpp"
#include "sprite/sprite.hpp"
+#include "supertux/main.hpp"
+#include "supertux/object_factory.hpp"
+#include "supertux/sector.hpp"
namespace {
- const float MIN_INTENSITY = 0.8f;
- const float ALPHA_SOLID = 0.7f;
- const float ALPHA_NONSOLID = 0.3f;
- const float MIN_SOLIDTIME = 1.0f;
- const float SWITCH_DELAY = 0.1f; /**< seconds to wait for stable conditions until switching solidity */
+const float MIN_INTENSITY = 0.8f;
+const float ALPHA_SOLID = 0.7f;
+const float ALPHA_NONSOLID = 0.3f;
+const float MIN_SOLIDTIME = 1.0f;
+const float SWITCH_DELAY = 0.1f; /**< seconds to wait for stable conditions until switching solidity */
}
-MagicBlock::MagicBlock(const lisp::Lisp& lisp)
- : MovingSprite(lisp, "images/objects/magicblock/magicblock.sprite"),
- is_solid(false), solid_time(0), switch_delay(0), light(1.0f,1.0f,1.0f)
+MagicBlock::MagicBlock(const Reader& lisp)
+ : MovingSprite(lisp, "images/objects/magicblock/magicblock.sprite"),
+ is_solid(false), solid_time(0), switch_delay(0), light(1.0f,1.0f,1.0f)
{
set_group(COLGROUP_STATIC);
//get color from lisp
bool lighting_ok;
if(black) {
lighting_ok = (light.red >= trigger_red || light.green >= trigger_green
- || light.blue >= trigger_blue);
+ || light.blue >= trigger_blue);
}else{
lighting_ok = (light.red >= trigger_red && light.green >= trigger_green
- && light.blue >= trigger_blue);
+ && light.blue >= trigger_blue);
}
// overrule lighting_ok if switch_delay has not yet passed
}
IMPLEMENT_FACTORY(MagicBlock, "magicblock");
+
+/* EOF */
-// $Id$
-//
// SuperTux - MagicBlock
//
// Magic Blocks are tile-like game objects that are sensitive to
//
// Copyright (C) 2006 Wolfgang Becker <uafr@gmx.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef SUPERTUX_MAGICBLOCK_H
-#define SUPERTUX_MAGICBLOCK_H
+#ifndef HEADER_SUPERTUX_OBJECT_MAGICBLOCK_HPP
+#define HEADER_SUPERTUX_OBJECT_MAGICBLOCK_HPP
-#include "moving_sprite.hpp"
-#include "lisp/lisp.hpp"
+#include "object/moving_sprite.hpp"
class MagicBlock: public MovingSprite
{
public:
- MagicBlock(const lisp::Lisp& reader);
+ MagicBlock(const Reader& reader);
bool collides(GameObject& other, const CollisionHit& hit);
HitResponse collision(GameObject& other, const CollisionHit& hit);
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux - MovingSprite Base Class
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include <config.h>
-
-#include <stdexcept>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "moving_sprite.hpp"
-#include "video/drawing_context.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "sector.hpp"
-#include "object_factory.hpp"
+#include "object/moving_sprite.hpp"
#include "sprite/sprite.hpp"
+#include "sprite/sprite_manager.hpp"
MovingSprite::MovingSprite(const Vector& pos, const std::string& sprite_name, int layer, CollisionGroup collision_group)
- : sprite_name(sprite_name), layer(layer)
+ : sprite_name(sprite_name), layer(layer)
{
bbox.set_pos(pos);
sprite = sprite_manager->create(sprite_name);
set_group(collision_group);
}
-MovingSprite::MovingSprite(const lisp::Lisp& reader, const Vector& pos, int layer, CollisionGroup collision_group)
- : layer(layer)
+MovingSprite::MovingSprite(const Reader& reader, const Vector& pos, int layer, CollisionGroup collision_group)
+ : layer(layer)
{
bbox.set_pos(pos);
if (!reader.get("sprite", sprite_name))
set_group(collision_group);
}
-MovingSprite::MovingSprite(const lisp::Lisp& reader, const std::string& sprite_name, int layer, CollisionGroup collision_group)
- : sprite_name(sprite_name), layer(layer)
+MovingSprite::MovingSprite(const Reader& reader, const std::string& sprite_name, int layer, CollisionGroup collision_group)
+ : sprite_name(sprite_name), layer(layer)
{
reader.get("x", bbox.p1.x);
reader.get("y", bbox.p1.y);
set_group(collision_group);
}
-MovingSprite::MovingSprite(const lisp::Lisp& reader, int layer, CollisionGroup collision_group)
- : layer(layer)
+MovingSprite::MovingSprite(const Reader& reader, int layer, CollisionGroup collision_group)
+ : layer(layer)
{
reader.get("x", bbox.p1.x);
reader.get("y", bbox.p1.y);
set_group(collision_group);
}
-MovingSprite::MovingSprite(const MovingSprite& other)
- : MovingObject(other), layer(other.layer)
+MovingSprite::MovingSprite(const MovingSprite& other) :
+ MovingObject(other),
+ layer(other.layer)
{
- sprite = new Sprite(*other.sprite);
+ sprite.reset(new Sprite(*other.sprite));
}
-
-MovingSprite&
-MovingSprite::operator=(const MovingSprite& other)
-{
+/*
+ MovingSprite&
+ MovingSprite::operator=(const MovingSprite& other)
+ {
if (this == &other)
- return *this;
+ return *this;
delete sprite;
sprite = new Sprite(*other.sprite);
layer = other.layer;
return *this;
-}
-
+ }
+*/
MovingSprite::~MovingSprite()
{
- delete sprite;
}
void
set_size(w, h);
set_pos(get_anchor_pos(old_bbox, w, h, anchorPoint));
}
+
+/* EOF */
-// $Id$
-//
// SuperTux - MovingSprite Base Class
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#ifndef __MOVING_SPRITE_H__
-#define __MOVING_SPRITE_H__
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <string>
+#ifndef HEADER_SUPERTUX_OBJECT_MOVING_SPRITE_HPP
+#define HEADER_SUPERTUX_OBJECT_MOVING_SPRITE_HPP
-#include "moving_object.hpp"
-#include "video/drawing_request.hpp"
#include "object/anchor_point.hpp"
+#include "supertux/moving_object.hpp"
+#include "util/reader_fwd.hpp"
+#include "video/drawing_request.hpp"
-namespace lisp {
-class Lisp;
-}
class Sprite;
/**
class MovingSprite : public MovingObject
{
public:
- MovingSprite(const Vector& pos, const std::string& sprite_name, int layer = LAYER_OBJECTS, CollisionGroup collision_group = COLGROUP_MOVING);
- MovingSprite(const lisp::Lisp& reader, const Vector& pos, int layer = LAYER_OBJECTS, CollisionGroup collision_group = COLGROUP_MOVING);
- MovingSprite(const lisp::Lisp& reader, const std::string& sprite_name, int layer = LAYER_OBJECTS, CollisionGroup collision_group = COLGROUP_MOVING);
- MovingSprite(const lisp::Lisp& reader, int layer = LAYER_OBJECTS, CollisionGroup collision_group = COLGROUP_MOVING);
+ MovingSprite(const Vector& pos,
+ const std::string& sprite_name,
+ int layer = LAYER_OBJECTS,
+ CollisionGroup collision_group = COLGROUP_MOVING);
+ MovingSprite(const Reader& reader,
+ const Vector& pos,
+ int layer = LAYER_OBJECTS,
+ CollisionGroup collision_group = COLGROUP_MOVING);
+ MovingSprite(const Reader& reader,
+ const std::string& sprite_name,
+ int layer = LAYER_OBJECTS,
+ CollisionGroup collision_group = COLGROUP_MOVING);
+ MovingSprite(const Reader& reader,
+ int layer = LAYER_OBJECTS,
+ CollisionGroup collision_group = COLGROUP_MOVING);
MovingSprite(const MovingSprite& moving_sprite);
- MovingSprite& operator=(const MovingSprite& moving_sprite);
+ //MovingSprite& operator=(const MovingSprite& moving_sprite);
~MovingSprite();
virtual void draw(DrawingContext& context);
protected:
std::string sprite_name;
- Sprite* sprite;
+ std::auto_ptr<Sprite> sprite;
int layer; /**< Sprite's z-position. Refer to video/drawing_context.hpp for sensible values. */
- /**
- * set new action for sprite and resize bounding box.
- * use with care as you can easily get stuck when resizing the bounding box.
- */
+ /** set new action for sprite and resize bounding box. use with
+ care as you can easily get stuck when resizing the bounding box. */
void set_action(const std::string& action, int loops);
- /**
- * set new action for sprite and re-center bounding box.
- * use with care as you can easily get stuck when resizing the bounding box.
- */
+ /** set new action for sprite and re-center bounding box. use with
+ care as you can easily get stuck when resizing the bounding
+ box. */
void set_action_centered(const std::string& action, int loops);
- /**
- * set new action for sprite and align bounding boxes at anchorPoint.
- * use with care as you can easily get stuck when resizing the bounding box.
- */
+ /** set new action for sprite and align bounding boxes at
+ anchorPoint. use with care as you can easily get stuck when
+ resizing the bounding box. */
void set_action(const std::string& action, int loops, AnchorPoint anchorPoint);
+
+private:
+ //MovingSprite(const MovingSprite&);
+ MovingSprite& operator=(const MovingSprite&);
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "oneup.hpp"
-#include "resources.hpp"
-#include "player.hpp"
-#include "player_status.hpp"
-#include "sector.hpp"
-#include "level.hpp"
-#include "statistics.hpp"
-#include "video/drawing_context.hpp"
+#include "object/oneup.hpp"
+#include "object/player.hpp"
+#include "supertux/sector.hpp"
-OneUp::OneUp(const Vector& pos, Direction direction)
- : MovingSprite(pos, "images/powerups/1up/1up.sprite", LAYER_FLOATINGOBJECTS, COLGROUP_TOUCHABLE)
+OneUp::OneUp(const Vector& pos, Direction direction) :
+ MovingSprite(pos, "images/powerups/1up/1up.sprite", LAYER_FLOATINGOBJECTS, COLGROUP_TOUCHABLE)
{
physic.set_velocity((direction == LEFT)?-100:100, -400);
}
}
return FORCE_MOVE;
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __ONEUP_H__
-#define __ONEUP_H__
+#ifndef HEADER_SUPERTUX_OBJECT_ONEUP_HPP
+#define HEADER_SUPERTUX_OBJECT_ONEUP_HPP
#include "object/moving_sprite.hpp"
-#include "physic.hpp"
-#include "direction.hpp"
+#include "supertux/direction.hpp"
+#include "supertux/physic.hpp"
-class OneUp : public MovingSprite, private UsesPhysic
+class OneUp : public MovingSprite
{
public:
OneUp(const Vector& pos, Direction direction = RIGHT);
- virtual OneUp* clone() const { return new OneUp(*this); }
virtual void update(float elapsed_time);
virtual HitResponse collision(GameObject& other, const CollisionHit& hit);
+
+private:
+ Physic physic;
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <config.h>
+#include "object/particles.hpp"
#include <math.h>
-#include "particles.hpp"
-#include "sector.hpp"
-#include "camera.hpp"
-#include "main.hpp"
-#include "random_generator.hpp"
+#include "math/random_generator.hpp"
+#include "object/camera.hpp"
+#include "supertux/main.hpp"
+#include "supertux/sector.hpp"
+#include "video/drawing_context.hpp"
Particles::Particles(const Vector& epicenter, int min_angle, int max_angle,
- const Vector& initial_velocity, const Vector& acceleration, int number,
- Color color_, int size_, float life_time, int drawing_layer_)
- : accel(acceleration), color(color_), size(size_), drawing_layer(drawing_layer_)
+ const Vector& initial_velocity, const Vector& acceleration, int number,
+ Color color_, int size_, float life_time, int drawing_layer_) :
+ accel(acceleration),
+ color(color_),
+ size(size_),
+ drawing_layer(drawing_layer_)
{
if(life_time == 0) {
live_forever = true;
// create particles
for(int p = 0; p < number; p++)
- {
+ {
Particle* particle = new Particle;
particle->pos = epicenter;
float angle = systemRandom.rand(min_angle, max_angle)
- * (M_PI / 180); // convert to radius (radians?)
+ * (M_PI / 180); // convert to radius (radians?)
particle->vel.x = /*fabs*/(sin(angle)) * initial_velocity.x;
-// if(angle >= M_PI && angle < M_PI*2)
-// particle->vel.x *= -1; // work around to fix signal
+ // if(angle >= M_PI && angle < M_PI*2)
+ // particle->vel.x *= -1; // work around to fix signal
particle->vel.y = /*fabs*/(cos(angle)) * initial_velocity.y;
-// if(angle >= M_PI_2 && angle < 3*M_PI_2)
-// particle->vel.y *= -1;
+ // if(angle >= M_PI_2 && angle < 3*M_PI_2)
+ // particle->vel.y *= -1;
particles.push_back(particle);
- }
+ }
}
Particles::~Particles()
context.draw_filled_rect((*i)->pos, Vector(size,size), color,drawing_layer);
}
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef SUPERTUX_PARTICLES_HPP
-#define SUPERTUX_PARTICLES_HPP
+#ifndef HEADER_SUPERTUX_OBJECT_PARTICLES_HPP
+#define HEADER_SUPERTUX_OBJECT_PARTICLES_HPP
#include "math/vector.hpp"
-#include "game_object.hpp"
-#include "timer.hpp"
+#include "supertux/game_object.hpp"
+#include "supertux/timer.hpp"
#include "video/color.hpp"
class Particles : public GameObject
struct Particle {
Vector pos, vel;
-// float angle;
- };
+ // float angle;
+ };
std::vector <Particle*> particles;
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <config.h>
+#include "object/particlesystem.hpp"
-#include <iostream>
#include <cmath>
-#include "particlesystem.hpp"
+#include "math/random_generator.hpp"
+#include "supertux/main.hpp"
#include "video/drawing_context.hpp"
-#include "lisp/parser.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-#include "resources.hpp"
-#include "main.hpp"
-#include "object/camera.hpp"
-#include "random_generator.hpp"
-
-ParticleSystem::ParticleSystem(float max_particle_size)
- : max_particle_size(max_particle_size)
+
+ParticleSystem::ParticleSystem(float max_particle_size) :
+ max_particle_size(max_particle_size)
{
virtual_width = SCREEN_WIDTH + max_particle_size * 2;
virtual_height = SCREEN_HEIGHT + max_particle_size *2;
pos.y = fmodf(particle->pos.y - scrolly, virtual_height);
if(pos.y < 0) pos.y += virtual_height;
-
//if(pos.x > virtual_width) pos.x -= virtual_width;
//if(pos.y > virtual_height) pos.y -= virtual_height;
}
void
-SnowParticleSystem::parse(const lisp::Lisp& reader)
+SnowParticleSystem::parse(const Reader& reader)
{
reader.get("z-pos", z_pos);
}
-void
-SnowParticleSystem::write(lisp::Writer& writer)
-{
- writer.start_list("particles-snow");
- writer.write("z-pos", z_pos);
- writer.end_list("particles-snow");
-}
-
SnowParticleSystem::~SnowParticleSystem()
{
for(int i=0;i<3;++i)
}
void
-GhostParticleSystem::parse(const lisp::Lisp& reader)
+GhostParticleSystem::parse(const Reader& reader)
{
reader.get("z-pos", z_pos);
}
-void
-GhostParticleSystem::write(lisp::Writer& writer)
-{
- writer.start_list("particles-ghosts");
- writer.write("z-pos", z_pos);
- writer.end_list("particles-ghosts");
-}
-
GhostParticleSystem::~GhostParticleSystem()
{
for(int i=0;i<2;++i)
}
CloudParticleSystem::CloudParticleSystem()
- : ParticleSystem(128)
+ : ParticleSystem(128)
{
cloudimage = new Surface("images/objects/particles/cloud.png");
}
void
-CloudParticleSystem::parse(const lisp::Lisp& reader)
+CloudParticleSystem::parse(const Reader& reader)
{
reader.get("z-pos", z_pos);
}
-void
-CloudParticleSystem::write(lisp::Writer& writer)
-{
- writer.start_list("particles-clouds");
- writer.write("z-pos", z_pos);
- writer.end_list("particles-clouds");
-}
-
CloudParticleSystem::~CloudParticleSystem()
{
delete cloudimage;
particle->pos.x += particle->speed * elapsed_time;
}
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef SUPERTUX_PARTICLESYSTEM_H
-#define SUPERTUX_PARTICLESYSTEM_H
+#ifndef HEADER_SUPERTUX_OBJECT_PARTICLESYSTEM_HPP
+#define HEADER_SUPERTUX_OBJECT_PARTICLESYSTEM_HPP
#include <vector>
-#include "video/surface.hpp"
-#include "game_object.hpp"
-#include "serializable.hpp"
-#include "sector.hpp"
#include "math/vector.hpp"
+#include "supertux/game_object.hpp"
+#include "util/reader.hpp"
-namespace lisp {
-class Lisp;
-}
+class Surface;
class DisplayManager;
class ParticleSystem : public GameObject
{
public:
- ParticleSystem(float max_particle_size = 60);
- virtual ~ParticleSystem();
+ ParticleSystem(float max_particle_size = 60);
+ virtual ~ParticleSystem();
- virtual void draw(DrawingContext& context);
+ virtual void draw(DrawingContext& context);
protected:
- float max_particle_size;
- int z_pos;
+ float max_particle_size;
+ int z_pos;
- class Particle
- {
- public:
- virtual ~Particle()
- { }
+ class Particle
+ {
+ public:
+ virtual ~Particle()
+ { }
- Vector pos;
- Surface* texture;
- };
+ Vector pos;
+ Surface* texture;
+ };
- std::vector<Particle*> particles;
- float virtual_width, virtual_height;
+ std::vector<Particle*> particles;
+ float virtual_width, virtual_height;
};
-class SnowParticleSystem : public ParticleSystem, public Serializable
+class SnowParticleSystem : public ParticleSystem
{
public:
- SnowParticleSystem();
- virtual ~SnowParticleSystem();
+ SnowParticleSystem();
+ virtual ~SnowParticleSystem();
- void parse(const lisp::Lisp& lisp);
- void write(lisp::Writer& writer);
+ void parse(const Reader& lisp);
- virtual void update(float elapsed_time);
+ virtual void update(float elapsed_time);
- std::string type() const
- { return "SnowParticleSystem"; }
+ std::string type() const
+ { return "SnowParticleSystem"; }
private:
- class SnowParticle : public Particle
- {
- public:
- float speed;
- float wobble;
- float anchorx;
- float drift_speed;
- };
-
- Surface* snowimages[3];
+ class SnowParticle : public Particle
+ {
+ public:
+ float speed;
+ float wobble;
+ float anchorx;
+ float drift_speed;
+ };
+
+ Surface* snowimages[3];
};
-class GhostParticleSystem : public ParticleSystem, public Serializable
+class GhostParticleSystem : public ParticleSystem
{
public:
- GhostParticleSystem();
- virtual ~GhostParticleSystem();
-
- void parse(const lisp::Lisp& lisp);
- void write(lisp::Writer& writer);
+ GhostParticleSystem();
+ virtual ~GhostParticleSystem();
- virtual void update(float elapsed_time);
+ void parse(const Reader& lisp);
+
+ virtual void update(float elapsed_time);
- std::string type() const
- { return "GhostParticleSystem"; }
+ std::string type() const
+ { return "GhostParticleSystem"; }
private:
- class GhostParticle : public Particle
- {
- public:
- float speed;
- };
+ class GhostParticle : public Particle
+ {
+ public:
+ float speed;
+ };
- Surface* ghosts[2];
+ Surface* ghosts[2];
};
-class CloudParticleSystem : public ParticleSystem, public Serializable
+class CloudParticleSystem : public ParticleSystem
{
public:
- CloudParticleSystem();
- virtual ~CloudParticleSystem();
+ CloudParticleSystem();
+ virtual ~CloudParticleSystem();
- void parse(const lisp::Lisp& lisp);
- void write(lisp::Writer& writer);
+ void parse(const Reader& lisp);
+
+ virtual void update(float elapsed_time);
- virtual void update(float elapsed_time);
-
- std::string type() const
- { return "CloudParticleSystem"; }
+ std::string type() const
+ { return "CloudParticleSystem"; }
private:
- class CloudParticle : public Particle
- {
- public:
- float speed;
- };
+ class CloudParticle : public Particle
+ {
+ public:
+ float speed;
+ };
- Surface* cloudimage;
+ Surface* cloudimage;
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <iostream>
-#include <cmath>
+#include "object/particlesystem_interactive.hpp"
+#include "supertux/main.hpp"
-#include "particlesystem_interactive.hpp"
-#include "video/drawing_context.hpp"
-#include "lisp/parser.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-#include "resources.hpp"
-#include "main.hpp"
-
-#include "tile.hpp"
-#include "tilemap.hpp"
#include "math/aatriangle.hpp"
-#include "collision.hpp"
-#include "collision_hit.hpp"
+#include "math/random_generator.hpp"
#include "object/camera.hpp"
#include "object/rainsplash.hpp"
-#include "badguy/bomb.hpp"
-#include "random_generator.hpp"
+#include "object/tilemap.hpp"
+#include "supertux/collision.hpp"
+#include "supertux/tile.hpp"
//TODO: Find a way to make rain collide with objects like bonus blocks
// Add an option to set rain strength
// Fix rain being "respawned" over solid tiles
ParticleSystem_Interactive::ParticleSystem_Interactive()
{
- virtual_width = SCREEN_WIDTH;
- virtual_height = SCREEN_HEIGHT;
- z_pos = 0;
+ virtual_width = SCREEN_WIDTH;
+ virtual_height = SCREEN_HEIGHT;
+ z_pos = 0;
}
ParticleSystem_Interactive::~ParticleSystem_Interactive()
{
- std::vector<Particle*>::iterator i;
- for(i = particles.begin(); i != particles.end(); ++i) {
- delete *i;
- }
+ std::vector<Particle*>::iterator i;
+ for(i = particles.begin(); i != particles.end(); ++i) {
+ delete *i;
+ }
}
void ParticleSystem_Interactive::draw(DrawingContext& context)
{
context.push_transform();
- std::vector<Particle*>::iterator i;
- for(i = particles.begin(); i != particles.end(); ++i) {
- Particle* particle = *i;
- context.draw_surface(particle->texture, particle->pos, z_pos);
- }
+ std::vector<Particle*>::iterator i;
+ for(i = particles.begin(); i != particles.end(); ++i) {
+ Particle* particle = *i;
+ context.draw_surface(particle->texture, particle->pos, z_pos);
+ }
- context.pop_transform();
+ context.pop_transform();
}
int
}
}
-
// TODO don't use magic numbers here...
// did we collide at all?
RainParticleSystem::RainParticleSystem()
{
- rainimages[0] = new Surface("images/objects/particles/rain0.png");
- rainimages[1] = new Surface("images/objects/particles/rain1.png");
-
- virtual_width = SCREEN_WIDTH * 2;
-
- // create some random raindrops
- size_t raindropcount = size_t(virtual_width/6.0);
- for(size_t i=0; i<raindropcount; ++i) {
- RainParticle* particle = new RainParticle;
- particle->pos.x = systemRandom.rand(int(virtual_width));
- particle->pos.y = systemRandom.rand(int(virtual_height));
- int rainsize = systemRandom.rand(2);
- particle->texture = rainimages[rainsize];
- do {
- particle->speed = (rainsize+1)*45 + systemRandom.randf(3.6);
- } while(particle->speed < 1);
- particle->speed *= 10; // gravity
-
- particles.push_back(particle);
- }
+ rainimages[0] = new Surface("images/objects/particles/rain0.png");
+ rainimages[1] = new Surface("images/objects/particles/rain1.png");
+
+ virtual_width = SCREEN_WIDTH * 2;
+
+ // create some random raindrops
+ size_t raindropcount = size_t(virtual_width/6.0);
+ for(size_t i=0; i<raindropcount; ++i) {
+ RainParticle* particle = new RainParticle;
+ particle->pos.x = systemRandom.rand(int(virtual_width));
+ particle->pos.y = systemRandom.rand(int(virtual_height));
+ int rainsize = systemRandom.rand(2);
+ particle->texture = rainimages[rainsize];
+ do {
+ particle->speed = (rainsize+1)*45 + systemRandom.randf(3.6);
+ } while(particle->speed < 1);
+ particle->speed *= 10; // gravity
+
+ particles.push_back(particle);
+ }
}
void
-RainParticleSystem::parse(const lisp::Lisp& reader)
+RainParticleSystem::parse(const Reader& reader)
{
reader.get("z-pos", z_pos);
}
-void
-RainParticleSystem::write(lisp::Writer& writer)
-{
- writer.start_list("particles-rain");
- writer.write("z-pos", z_pos);
- writer.end_list("particles-rain");
-}
-
RainParticleSystem::~RainParticleSystem()
{
for(int i=0;i<2;++i)
void RainParticleSystem::update(float elapsed_time)
{
- std::vector<Particle*>::iterator i;
- for(
- i = particles.begin(); i != particles.end(); ++i) {
- RainParticle* particle = (RainParticle*) *i;
- float movement = particle->speed * elapsed_time;
- float abs_x = Sector::current()->camera->get_translation().x;
- float abs_y = Sector::current()->camera->get_translation().y;
- particle->pos.y += movement;
- particle->pos.x -= movement;
- int col = collision(particle, Vector(-movement, movement));
- if ((particle->pos.y > SCREEN_HEIGHT + abs_y) || (col >= 0)) {
- //Create rainsplash
- if ((particle->pos.y <= SCREEN_HEIGHT + abs_y) && (col >= 1)){
- bool vertical = (col == 2);
- int splash_x, splash_y;
- if (!vertical) { //check if collision happened from above
- splash_x = int(particle->pos.x);
- splash_y = int(particle->pos.y) - (int(particle->pos.y) % 32) + 32;
- Sector::current()->add_object(new RainSplash(Vector(splash_x, splash_y),vertical));
- }
- // Uncomment the following to display vertical splashes, too
- /* else {
- splash_x = int(particle->pos.x) - (int(particle->pos.x) % 32) + 32;
- splash_y = int(particle->pos.y);
- Sector::current()->add_object(new RainSplash(Vector(splash_x, splash_y),vertical));
- } */
- }
- int new_x = systemRandom.rand(int(virtual_width)) + int(abs_x);
- int new_y = 0;
- //FIXME: Don't move particles over solid tiles
- particle->pos.x = new_x;
- particle->pos.y = new_y;
+ std::vector<Particle*>::iterator i;
+ for(
+ i = particles.begin(); i != particles.end(); ++i) {
+ RainParticle* particle = (RainParticle*) *i;
+ float movement = particle->speed * elapsed_time;
+ float abs_x = Sector::current()->camera->get_translation().x;
+ float abs_y = Sector::current()->camera->get_translation().y;
+ particle->pos.y += movement;
+ particle->pos.x -= movement;
+ int col = collision(particle, Vector(-movement, movement));
+ if ((particle->pos.y > SCREEN_HEIGHT + abs_y) || (col >= 0)) {
+ //Create rainsplash
+ if ((particle->pos.y <= SCREEN_HEIGHT + abs_y) && (col >= 1)){
+ bool vertical = (col == 2);
+ int splash_x, splash_y;
+ if (!vertical) { //check if collision happened from above
+ splash_x = int(particle->pos.x);
+ splash_y = int(particle->pos.y) - (int(particle->pos.y) % 32) + 32;
+ Sector::current()->add_object(new RainSplash(Vector(splash_x, splash_y),vertical));
}
+ // Uncomment the following to display vertical splashes, too
+ /* else {
+ splash_x = int(particle->pos.x) - (int(particle->pos.x) % 32) + 32;
+ splash_y = int(particle->pos.y);
+ Sector::current()->add_object(new RainSplash(Vector(splash_x, splash_y),vertical));
+ } */
+ }
+ int new_x = systemRandom.rand(int(virtual_width)) + int(abs_x);
+ int new_y = 0;
+ //FIXME: Don't move particles over solid tiles
+ particle->pos.x = new_x;
+ particle->pos.y = new_y;
}
+ }
}
CometParticleSystem::CometParticleSystem()
{
- cometimages[0] = new Surface("images/creatures/mr_bomb/exploding-left-0.png");
- cometimages[1] = new Surface("images/creatures/mr_bomb/exploding-left-0.png");
-
- virtual_width = SCREEN_WIDTH * 2;
-
- // create some random comets
- size_t cometcount = 2;
- for(size_t i=0; i<cometcount; ++i) {
- CometParticle* particle = new CometParticle;
- particle->pos.x = systemRandom.rand(int(virtual_width));
- particle->pos.y = systemRandom.rand(int(virtual_height));
- int cometsize = systemRandom.rand(2);
- particle->texture = cometimages[cometsize];
- do {
- particle->speed = (cometsize+1)*30 + systemRandom.randf(3.6);
- } while(particle->speed < 1);
- particle->speed *= 10; // gravity
-
- particles.push_back(particle);
- }
+ cometimages[0] = new Surface("images/creatures/mr_bomb/exploding-left-0.png");
+ cometimages[1] = new Surface("images/creatures/mr_bomb/exploding-left-0.png");
+
+ virtual_width = SCREEN_WIDTH * 2;
+
+ // create some random comets
+ size_t cometcount = 2;
+ for(size_t i=0; i<cometcount; ++i) {
+ CometParticle* particle = new CometParticle;
+ particle->pos.x = systemRandom.rand(int(virtual_width));
+ particle->pos.y = systemRandom.rand(int(virtual_height));
+ int cometsize = systemRandom.rand(2);
+ particle->texture = cometimages[cometsize];
+ do {
+ particle->speed = (cometsize+1)*30 + systemRandom.randf(3.6);
+ } while(particle->speed < 1);
+ particle->speed *= 10; // gravity
+
+ particles.push_back(particle);
+ }
}
void
-CometParticleSystem::parse(const lisp::Lisp& reader)
+CometParticleSystem::parse(const Reader& reader)
{
reader.get("z-pos", z_pos);
}
-void
-CometParticleSystem::write(lisp::Writer& writer)
-{
- writer.start_list("particles-comets");
- writer.write("z-pos", z_pos);
- writer.end_list("particles-comets");
-}
-
CometParticleSystem::~CometParticleSystem()
{
for(int i=0;i<2;++i)
{
(void) elapsed_time;
#if 0
- std::vector<Particle*>::iterator i;
- for(
- i = particles.begin(); i != particles.end(); ++i) {
- CometParticle* particle = (CometParticle*) *i;
- float movement = particle->speed * elapsed_time;
- float abs_x = Sector::current()->camera->get_translation().x;
- float abs_y = Sector::current()->camera->get_translation().y;
- particle->pos.y += movement;
- particle->pos.x -= movement;
- int col = collision(particle, Vector(-movement, movement));
- if ((particle->pos.y > SCREEN_HEIGHT + abs_y) || (col >= 0)) {
- if ((particle->pos.y <= SCREEN_HEIGHT + abs_y) && (col >= 1)) {
- Sector::current()->add_object(new Bomb(particle->pos, LEFT));
- }
- int new_x = systemRandom.rand(int(virtual_width)) + int(abs_x);
- int new_y = 0;
- //FIXME: Don't move particles over solid tiles
- particle->pos.x = new_x;
- particle->pos.y = new_y;
- }
+ std::vector<Particle*>::iterator i;
+ for(
+ i = particles.begin(); i != particles.end(); ++i) {
+ CometParticle* particle = (CometParticle*) *i;
+ float movement = particle->speed * elapsed_time;
+ float abs_x = Sector::current()->camera->get_translation().x;
+ float abs_y = Sector::current()->camera->get_translation().y;
+ particle->pos.y += movement;
+ particle->pos.x -= movement;
+ int col = collision(particle, Vector(-movement, movement));
+ if ((particle->pos.y > SCREEN_HEIGHT + abs_y) || (col >= 0)) {
+ if ((particle->pos.y <= SCREEN_HEIGHT + abs_y) && (col >= 1)) {
+ Sector::current()->add_object(new Bomb(particle->pos, LEFT));
+ }
+ int new_x = systemRandom.rand(int(virtual_width)) + int(abs_x);
+ int new_y = 0;
+ //FIXME: Don't move particles over solid tiles
+ particle->pos.x = new_x;
+ particle->pos.y = new_y;
}
+ }
#endif
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#ifndef SUPERTUX_PARTICLESYSTEM_INTERACTIVE_H
-#define SUPERTUX_PARTICLESYSTEM_INTERACTIVE_H
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <vector>
+#ifndef HEADER_SUPERTUX_OBJECT_PARTICLESYSTEM_INTERACTIVE_HPP
+#define HEADER_SUPERTUX_OBJECT_PARTICLESYSTEM_INTERACTIVE_HPP
-#include "video/surface.hpp"
-#include "game_object.hpp"
-#include "serializable.hpp"
-#include "sector.hpp"
#include "math/vector.hpp"
+#include "supertux/game_object.hpp"
+#include "supertux/sector.hpp"
-namespace lisp {
-class Lisp;
-}
-
+class Surface;
class DisplayManager;
/**
class ParticleSystem_Interactive : public GameObject
{
public:
- ParticleSystem_Interactive();
- virtual ~ParticleSystem_Interactive();
+ ParticleSystem_Interactive();
+ virtual ~ParticleSystem_Interactive();
- virtual void draw(DrawingContext& context);
+ virtual void draw(DrawingContext& context);
protected:
- int z_pos;
+ int z_pos;
- class Particle
- {
- public:
- virtual ~Particle()
- { }
+ class Particle
+ {
+ public:
+ virtual ~Particle()
+ { }
- Vector pos;
- Surface* texture;
- };
+ Vector pos;
+ Surface* texture;
+ };
- std::vector<Particle*> particles;
- float virtual_width, virtual_height;
- int collision(Particle* particle, Vector movement);
+ std::vector<Particle*> particles;
+ float virtual_width, virtual_height;
+ int collision(Particle* particle, Vector movement);
};
-class RainParticleSystem : public ParticleSystem_Interactive, public Serializable
+class RainParticleSystem : public ParticleSystem_Interactive
{
public:
- RainParticleSystem();
- virtual ~RainParticleSystem();
+ RainParticleSystem();
+ virtual ~RainParticleSystem();
- void parse(const lisp::Lisp& lisp);
- void write(lisp::Writer& writer);
+ void parse(const Reader& lisp);
- virtual void update(float elapsed_time);
+ virtual void update(float elapsed_time);
- std::string type() const
- { return "RainParticleSystem"; }
+ std::string type() const
+ { return "RainParticleSystem"; }
private:
- class RainParticle : public Particle
- {
- public:
- float speed;
- };
+ class RainParticle : public Particle
+ {
+ public:
+ float speed;
+ };
- Surface* rainimages[2];
+ Surface* rainimages[2];
};
-class CometParticleSystem : public ParticleSystem_Interactive, public Serializable
+class CometParticleSystem : public ParticleSystem_Interactive
{
public:
- CometParticleSystem();
- virtual ~CometParticleSystem();
+ CometParticleSystem();
+ virtual ~CometParticleSystem();
- void parse(const lisp::Lisp& lisp);
- void write(lisp::Writer& writer);
+ void parse(const Reader& lisp);
+ void write(lisp::Writer& writer);
- virtual void update(float elapsed_time);
+ virtual void update(float elapsed_time);
- std::string type() const
- { return "CometParticleSystem"; }
+ std::string type() const
+ { return "CometParticleSystem"; }
private:
- class CometParticle : public Particle
- {
- public:
- float speed;
- };
+ class CometParticle : public Particle
+ {
+ public:
+ float speed;
+ };
- Surface* cometimages[2];
+ Surface* cometimages[2];
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux Path
// Copyright (C) 2005 Philipp <balinor@pnxs.de>
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-#include <config.h>
-
-#include "path.hpp"
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "lisp/writer.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/list_iterator.hpp"
-#include "log.hpp"
+#include "object/path.hpp"
-#include <assert.h>
-#include <iostream>
-#include <stdexcept>
#include <sstream>
+#include <stdexcept>
-Path::Path()
+#include "lisp/list_iterator.hpp"
+#include "util/log.hpp"
+
+Path::Path() :
+ nodes(),
+ mode()
{
}
}
void
-Path::read(const lisp::Lisp& reader)
+Path::read(const Reader& reader)
{
lisp::ListIterator iter(&reader);
Node node;
node.time = 1;
if( (!node_lisp->get("x", node.position.x) ||
- !node_lisp->get("y", node.position.y)))
+ !node_lisp->get("y", node.position.y)))
throw std::runtime_error("Path node without x and y coordinate specified");
node_lisp->get("time", node.time);
throw std::runtime_error("Path with zero nodes");
}
-void
-Path::write(lisp::Writer& writer)
-{
- writer.start_list("path");
-
- switch(mode) {
- case ONE_SHOT:
- writer.write("mode", "oneshot");
- break;
- case PING_PONG:
- writer.write("mode", "pingpong");
- break;
- case CIRCULAR:
- writer.write("mode", "circular");
- break;
- default:
- log_warning << "Don't know how to write mode " << (int) mode << " ?!?" << std::endl;
- break;
- }
-
- for (size_t i=0; i < nodes.size(); i++) {
- const Node& node = nodes[i];
-
- writer.start_list("node");
- writer.write("x", node.position.x);
- writer.write("y", node.position.y);
- writer.write("time", node.time);
-
- writer.end_list("node");
- }
-
- writer.end_list("path");
-}
-
Vector
Path::get_base() const
{
return farthest_node_id;
}
+/* EOF */
-// $Id$
-//
// SuperTux Path
// Copyright (C) 2005 Philipp <balinor@pnxs.de>
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-#ifndef __PATH_HPP__
-#define __PATH_HPP__
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_OBJECT_PATH_HPP
+#define HEADER_SUPERTUX_OBJECT_PATH_HPP
#include <vector>
+
#include "math/vector.hpp"
-#include "lisp/lisp.hpp"
-#include "serializable.hpp"
+#include "util/reader_fwd.hpp"
+#include "util/writer_fwd.hpp"
-class Path : public Serializable
+class Path
{
public:
Path();
~Path();
- void read(const lisp::Lisp& reader);
- void write(lisp::Writer& writer);
+ void read(const Reader& reader);
Vector get_base() const;
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "path_walker.hpp"
+#include "object/path_walker.hpp"
#include <math.h>
#include <assert.h>
-PathWalker::PathWalker(const Path* path, bool running)
- : path(path), running(running), current_node_nr(0), next_node_nr(0), stop_at_node_nr(running?-1:0), node_time(0),
- walking_speed(1.0)
+PathWalker::PathWalker(const Path* path, bool running) :
+ path(path),
+ running(running),
+ current_node_nr(0),
+ next_node_nr(0),
+ stop_at_node_nr(running?-1:0),
+ node_time(0),
+ walking_speed(1.0)
{
node_mult = 1 / path->nodes[0].time;
next_node_nr = path->nodes.size() > 1 ? 1 : 0;
stop_at_node_nr = next_node_nr;
}
-
void
PathWalker::advance_node()
{
next_node_nr = 0;
walking_speed = 0;
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_OBJECT_PATH_WALKER_HPP
+#define HEADER_SUPERTUX_OBJECT_PATH_WALKER_HPP
-#ifndef __PATH_WALKER_HPP__
-#define __PATH_WALKER_HPP__
+#include <string.h>
-#include "path.hpp"
+#include "object/path.hpp"
/**
* A walker that travels along a path
float node_mult;
float walking_speed;
+
+private:
+ PathWalker(const PathWalker&);
+ PathWalker& operator=(const PathWalker&);
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
-
-#include "platform.hpp"
-
-#include <stdexcept>
-#include "log.hpp"
-#include "video/drawing_context.hpp"
-#include "resources.hpp"
-#include "player.hpp"
-#include "path.hpp"
-#include "path_walker.hpp"
-#include "sprite/sprite.hpp"
-#include "lisp/lisp.hpp"
-#include "object_factory.hpp"
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#include "object/platform.hpp"
+
+#include "object/player.hpp"
#include "scripting/platform.hpp"
#include "scripting/squirrel_util.hpp"
-#include "sector.hpp"
-
-Platform::Platform(const lisp::Lisp& reader)
- : MovingSprite(reader, Vector(0,0), LAYER_OBJECTS, COLGROUP_STATIC),
- speed(Vector(0,0)),
- automatic(false), player_contact(false), last_player_contact(false)
+#include "supertux/object_factory.hpp"
+#include "supertux/sector.hpp"
+#include "util/reader.hpp"
+
+Platform::Platform(const Reader& reader)
+ : MovingSprite(reader, Vector(0,0), LAYER_OBJECTS, COLGROUP_STATIC),
+ speed(Vector(0,0)),
+ automatic(false), player_contact(false), last_player_contact(false)
{
bool running = true;
reader.get("name", name);
bbox.set_pos(path->get_base());
}
-Platform::Platform(const Platform& other)
- : MovingSprite(other), ScriptInterface(other),
- speed(other.speed),
- automatic(other.automatic), player_contact(false), last_player_contact(false)
-{
+/*
+ Platform::Platform(const Platform& other) :
+ MovingSprite(other),
+ ScriptInterface(other),
+ speed(other.speed),
+ automatic(other.automatic),
+ player_contact(false),
+ last_player_contact(false)
+ {
name = other.name;
path.reset(new Path(*other.path));
walker.reset(new PathWalker(*other.walker));
walker->path = &*path;
-}
+ }
+*/
HitResponse
Platform::collision(GameObject& other, const CollisionHit& )
}
IMPLEMENT_FACTORY(Platform, "platform");
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __PLATFORM_H__
-#define __PLATFORM_H__
+#ifndef HEADER_SUPERTUX_OBJECT_PLATFORM_HPP
+#define HEADER_SUPERTUX_OBJECT_PLATFORM_HPP
-#include <memory>
-#include <string>
#include "object/moving_sprite.hpp"
-#include "object/path.hpp"
#include "object/path_walker.hpp"
-#include "script_interface.hpp"
+#include "supertux/script_interface.hpp"
/**
* This class is the base class for platforms that tux can stand on
*/
-class Platform : public MovingSprite, public ScriptInterface
+class Platform : public MovingSprite,
+ public ScriptInterface
{
public:
- Platform(const lisp::Lisp& reader);
+ Platform(const Reader& reader);
Platform(const Platform& platform);
- virtual Platform* clone() const { return new Platform(*this); }
virtual HitResponse collision(GameObject& other, const CollisionHit& hit);
virtual void update(float elapsed_time);
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include <config.h>
-#include "player.hpp"
+#include "object/player.hpp"
#include "audio/sound_manager.hpp"
#include "badguy/badguy.hpp"
-#include "control/codecontroller.hpp"
#include "control/joystickkeyboardcontroller.hpp"
-#include "display_effect.hpp"
-#include "log.hpp"
-#include "falling_coin.hpp"
-#include "game_session.hpp"
-#include "gettext.hpp"
-#include "main.hpp"
+#include "math/random_generator.hpp"
#include "object/bullet.hpp"
#include "object/camera.hpp"
+#include "object/display_effect.hpp"
+#include "object/falling_coin.hpp"
+#include "object/particles.hpp"
#include "object/portable.hpp"
#include "object/sprite_particle.hpp"
-#include "object/tilemap.hpp"
-#include "particles.hpp"
-#include "player_status.hpp"
-#include "random_generator.hpp"
-#include "sector.hpp"
#include "scripting/squirrel_util.hpp"
-#include "sprite/sprite.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "tile.hpp"
+#include "supertux/game_session.hpp"
+#include "supertux/main.hpp"
+#include "supertux/sector.hpp"
+#include "supertux/tile.hpp"
#include "trigger/climbable.hpp"
-#include <typeinfo>
#include <cmath>
-#include <iostream>
-#include <cassert>
//#define SWIMMING
namespace {
- static const int TILES_FOR_BUTTJUMP = 3;
- static const float BUTTJUMP_MIN_VELOCITY_Y = 400.0f;
- static const float SHOOTING_TIME = .150f;
-
- /** number of idle stages, including standing */
- static const unsigned int IDLE_STAGE_COUNT = 5;
- /**
- * how long to play each idle animation in milliseconds
- * '0' means the sprite action is played once before moving onto the next
- * animation
- */
- static const int IDLE_TIME[] = { 5000, 0, 2500, 0, 2500 };
- /** idle stages */
- static const std::string IDLE_STAGES[] =
- { "stand",
- "idle",
- "stand",
- "idle",
- "stand" };
-
- /** acceleration in horizontal direction when walking
- * (all accelerations are in pixel/s^2) */
- static const float WALK_ACCELERATION_X = 300;
- /** acceleration in horizontal direction when running */
- static const float RUN_ACCELERATION_X = 400;
- /** acceleration when skidding */
- static const float SKID_XM = 200;
- /** time of skidding in seconds */
- static const float SKID_TIME = .3f;
- /** maximum walk velocity (pixel/s) */
- static const float MAX_WALK_XM = 230;
- /** maximum run velocity (pixel/s) */
- static const float MAX_RUN_XM = 320;
- /** maximum horizontal climb velocity */
- static const float MAX_CLIMB_XM = 48;
- /** maximum vertical climb velocity */
- static const float MAX_CLIMB_YM = 128;
- /** instant velocity when tux starts to walk */
- static const float WALK_SPEED = 100;
-
- /** multiplied by WALK_ACCELERATION to give friction */
- static const float NORMAL_FRICTION_MULTIPLIER = 1.5f;
- /** multiplied by WALK_ACCELERATION to give friction */
- static const float ICE_FRICTION_MULTIPLIER = 0.1f;
- static const float ICE_ACCELERATION_MULTIPLIER = 0.25f;
-
- /** time of the kick (kicking mriceblock) animation */
- static const float KICK_TIME = .3f;
- /** time of tux cheering (currently unused) */
- static const float CHEER_TIME = 1.0f;
-
- /** if Tux cannot unduck for this long, he will get hurt */
- static const float UNDUCK_HURT_TIME = 0.25f;
- /** gravity is higher after the jump key is released before
- the apex of the jump is reached */
- static const float JUMP_EARLY_APEX_FACTOR = 3.0;
-
- static const float JUMP_GRACE_TIME = 0.25f; /**< time before hitting the ground that the jump button may be pressed (and still trigger a jump) */
-
- bool no_water = true;
+static const int TILES_FOR_BUTTJUMP = 3;
+static const float BUTTJUMP_MIN_VELOCITY_Y = 400.0f;
+static const float SHOOTING_TIME = .150f;
+
+/** number of idle stages, including standing */
+static const unsigned int IDLE_STAGE_COUNT = 5;
+/**
+ * how long to play each idle animation in milliseconds
+ * '0' means the sprite action is played once before moving onto the next
+ * animation
+ */
+static const int IDLE_TIME[] = { 5000, 0, 2500, 0, 2500 };
+/** idle stages */
+static const std::string IDLE_STAGES[] =
+{ "stand",
+ "idle",
+ "stand",
+ "idle",
+ "stand" };
+
+/** acceleration in horizontal direction when walking
+ * (all accelerations are in pixel/s^2) */
+static const float WALK_ACCELERATION_X = 300;
+/** acceleration in horizontal direction when running */
+static const float RUN_ACCELERATION_X = 400;
+/** acceleration when skidding */
+static const float SKID_XM = 200;
+/** time of skidding in seconds */
+static const float SKID_TIME = .3f;
+/** maximum walk velocity (pixel/s) */
+static const float MAX_WALK_XM = 230;
+/** maximum run velocity (pixel/s) */
+static const float MAX_RUN_XM = 320;
+/** maximum horizontal climb velocity */
+static const float MAX_CLIMB_XM = 48;
+/** maximum vertical climb velocity */
+static const float MAX_CLIMB_YM = 128;
+/** instant velocity when tux starts to walk */
+static const float WALK_SPEED = 100;
+
+/** multiplied by WALK_ACCELERATION to give friction */
+static const float NORMAL_FRICTION_MULTIPLIER = 1.5f;
+/** multiplied by WALK_ACCELERATION to give friction */
+static const float ICE_FRICTION_MULTIPLIER = 0.1f;
+static const float ICE_ACCELERATION_MULTIPLIER = 0.25f;
+
+/** time of the kick (kicking mriceblock) animation */
+static const float KICK_TIME = .3f;
+/** time of tux cheering (currently unused) */
+static const float CHEER_TIME = 1.0f;
+
+/** if Tux cannot unduck for this long, he will get hurt */
+static const float UNDUCK_HURT_TIME = 0.25f;
+/** gravity is higher after the jump key is released before
+ the apex of the jump is reached */
+static const float JUMP_EARLY_APEX_FACTOR = 3.0;
+
+static const float JUMP_GRACE_TIME = 0.25f; /**< time before hitting the ground that the jump button may be pressed (and still trigger a jump) */
+
+bool no_water = true;
}
-Player::Player(PlayerStatus* _player_status, const std::string& name)
- : scripting_controller(0),
- player_status(_player_status),
- scripting_controller_old(0),
- grabbed_object(NULL), ghost_mode(false), edit_mode(false), idle_stage(0),
- climbing(0)
+Player::Player(PlayerStatus* _player_status, const std::string& name) :
+ scripting_controller(0),
+ player_status(_player_status),
+ scripting_controller_old(0),
+ grabbed_object(NULL),
+ ghost_mode(false),
+ edit_mode(false),
+ idle_stage(0),
+ climbing(0)
{
this->name = name;
- controller = main_controller;
- scripting_controller = new CodeController();
+ controller = g_main_controller;
+ scripting_controller.reset(new CodeController());
sprite = sprite_manager->create("images/creatures/tux/tux.sprite");
airarrow.reset(new Surface("images/engine/hud/airarrow.png"));
idle_timer.start(IDLE_TIME[0]/1000.0f);
Player::~Player()
{
if (climbing) stop_climbing(*climbing);
- delete sprite;
- delete scripting_controller;
}
void
void
Player::use_scripting_controller(bool use_or_release)
{
- if ((use_or_release == true) && (controller != scripting_controller)) {
+ if ((use_or_release == true) && (controller != scripting_controller.get())) {
scripting_controller_old = get_controller();
- set_controller(scripting_controller);
+ set_controller(scripting_controller.get());
}
- if ((use_or_release == false) && (controller == scripting_controller)) {
+ if ((use_or_release == false) && (controller == scripting_controller.get())) {
set_controller(scripting_controller_old);
scripting_controller_old = 0;
}
Vector pspeed = Vector(0, 0);
Vector paccel = Vector(0, 0);
Sector::current()->add_object(new SpriteParticle("images/objects/particles/sparkle.sprite",
- // draw bright sparkle when there is lots of time left, dark sparkle when invincibility is about to end
- (invincible_timer.get_timeleft() > TUX_INVINCIBLE_TIME_WARNING) ?
- // make every other a longer sparkle to make trail a bit fuzzy
- (size_t(game_time*20)%2) ? "small" : "medium"
- :
- "dark", ppos, ANCHOR_MIDDLE, pspeed, paccel, LAYER_OBJECTS+1+5));
+ // draw bright sparkle when there is lots of time left, dark sparkle when invincibility is about to end
+ (invincible_timer.get_timeleft() > TUX_INVINCIBLE_TIME_WARNING) ?
+ // make every other a longer sparkle to make trail a bit fuzzy
+ (size_t(game_time*20)%2) ? "small" : "medium"
+ :
+ "dark", ppos, ANCHOR_MIDDLE, pspeed, paccel, LAYER_OBJECTS+1+5));
}
}
//Check speedlimit.
if( speedlimit > 0 && vx * dirsign >= speedlimit ) {
- vx = dirsign * speedlimit;
- ax = 0;
+ vx = dirsign * speedlimit;
+ ax = 0;
}
// changing directions?
}
void
-Player::early_jump_apex() {
- if(jump_early_apex) {
- return;
+Player::early_jump_apex()
+{
+ if (!jump_early_apex)
+ {
+ jump_early_apex = true;
+ physic.set_gravity_modifier(JUMP_EARLY_APEX_FACTOR);
}
- jump_early_apex = true;
- physic.set_gravity(physic.get_gravity() * JUMP_EARLY_APEX_FACTOR);
-};
+}
void
-Player::do_jump_apex() {
- if(!jump_early_apex) {
- return;
+Player::do_jump_apex()
+{
+ if (jump_early_apex)
+ {
+ jump_early_apex = false;
+ physic.set_gravity_modifier(1.0f);
}
- jump_early_apex = false;
- physic.set_gravity(physic.get_gravity() / JUMP_EARLY_APEX_FACTOR);
}
void
jump_button_timer.stop();
if (duck) {
// when running, only jump a little bit; else do a backflip
- if ((physic.get_velocity_x() != 0) || (controller->hold(Controller::LEFT)) || (controller->hold(Controller::RIGHT))) do_jump(-300); else do_backflip();
+ if ((physic.get_velocity_x() != 0) ||
+ (controller->hold(Controller::LEFT)) ||
+ (controller->hold(Controller::RIGHT)))
+ {
+ do_jump(-300);
+ }
+ else
+ {
+ do_backflip();
+ }
} else {
// jump a bit higher if we are running; else do a normal jump
if (fabs(physic.get_velocity_x()) > MAX_WALK_XM) do_jump(-580); else do_jump(-520);
if(!controller->hold(Controller::ACTION) && grabbed_object) {
// move the grabbed object a bit away from tux
Vector pos = get_pos() +
- Vector(dir == LEFT ? -bbox.get_width()-1 : bbox.get_width()+1,
- bbox.get_height()*0.66666 - 32);
+ Vector(dir == LEFT ? -bbox.get_width()-1 : bbox.get_width()+1,
+ bbox.get_height()*0.66666 - 32);
Rect dest(pos, pos + Vector(32, 32));
if(Sector::current()->is_free_of_movingstatics(dest)) {
MovingObject* moving_object = dynamic_cast<MovingObject*> (grabbed_object);
Player::try_grab()
{
if(controller->hold(Controller::ACTION) && !grabbed_object
- && !duck) {
- Sector* sector = Sector::current();
+ && !duck) {
+ Sector* sector = Sector::current();
Vector pos;
if(dir == LEFT) {
pos = Vector(bbox.get_left() - 5, bbox.get_bottom() - 16);
else if (idle_timer.check() || (IDLE_TIME[idle_stage] == 0 && sprite->animation_done())) {
idle_stage++;
if (idle_stage >= IDLE_STAGE_COUNT)
- idle_stage = 1;
+ idle_stage = 1;
idle_timer.start(IDLE_TIME[idle_stage]/1000.0f);
}
}
-
-/*
+ /*
// Tux is holding something
if ((grabbed_object != 0 && physic.get_velocity_y() == 0) ||
- (shooting_timer.get_timeleft() > 0 && !shooting_timer.check())) {
- if (duck) {
- } else {
- }
+ (shooting_timer.get_timeleft() > 0 && !shooting_timer.check())) {
+ if (duck) {
+ } else {
+ }
}
-*/
+ */
/* Draw Tux */
if (safe_timer.started() && size_t(game_time*40)%2)
physic.set_velocity_y(-300);
on_ground_flag = false;
Sector::current()->add_object(new Particles(
- Vector(get_bbox().p2.x, get_bbox().p2.y),
- 270+20, 270+40,
- Vector(280, -260), Vector(0, 300), 3, Color(.4f, .4f, .4f), 3, .8f,
- LAYER_OBJECTS+1));
+ Vector(get_bbox().p2.x, get_bbox().p2.y),
+ 270+20, 270+40,
+ Vector(280, -260), Vector(0, 300), 3, Color(.4f, .4f, .4f), 3, .8f,
+ LAYER_OBJECTS+1));
Sector::current()->add_object(new Particles(
- Vector(get_bbox().p1.x, get_bbox().p2.y),
- 90-40, 90-20,
- Vector(280, -260), Vector(0, 300), 3, Color(.4f, .4f, .4f), 3, .8f,
- LAYER_OBJECTS+1));
+ Vector(get_bbox().p1.x, get_bbox().p2.y),
+ 90-40, 90-20,
+ Vector(280, -260), Vector(0, 300), 3, Color(.4f, .4f, .4f), 3, .8f,
+ LAYER_OBJECTS+1));
}
} else if(hit.top) {
if(!completely && is_big()) {
if(player_status->bonus == FIRE_BONUS
- || player_status->bonus == ICE_BONUS) {
+ || player_status->bonus == ICE_BONUS) {
safe_timer.start(TUX_SAFE_TIME);
set_bonus(GROWUP_BONUS, true);
} else if(player_status->bonus == GROWUP_BONUS) {
{
// the numbers: starting x, starting y, velocity y
Sector::current()->add_object(new FallingCoin(get_pos() +
- Vector(systemRandom.rand(5), systemRandom.rand(-32,18)),
- systemRandom.rand(-100,100)));
+ Vector(systemRandom.rand(5), systemRandom.rand(-32,18)),
+ systemRandom.rand(-100,100)));
}
player_status->coins -= std::max(player_status->coins/10, 25);
}
if(get_pos().x >= camera->get_translation().x + SCREEN_WIDTH - bbox.get_width())
{
set_pos(Vector(
- camera->get_translation().x + SCREEN_WIDTH - bbox.get_width(),
- get_pos().y));
+ camera->get_translation().x + SCREEN_WIDTH - bbox.get_width(),
+ get_pos().y));
}
}
}
}
-
void
Player::set_edit_mode(bool enable)
{
physic.set_acceleration(0, 0);
}
-
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef SUPERTUX_PLAYER_H
-#define SUPERTUX_PLAYER_H
+#ifndef HEADER_SUPERTUX_OBJECT_PLAYER_HPP
+#define HEADER_SUPERTUX_OBJECT_PLAYER_HPP
-#include "timer.hpp"
-#include "direction.hpp"
-#include "moving_object.hpp"
-#include "physic.hpp"
#include "scripting/player.hpp"
-#include "player_status.hpp"
-#include "script_interface.hpp"
-
-#include <vector>
-#include <SDL.h>
+#include "supertux/direction.hpp"
+#include "supertux/moving_object.hpp"
+#include "supertux/physic.hpp"
+#include "supertux/player_status.hpp"
+#include "supertux/script_interface.hpp"
+#include "supertux/timer.hpp"
class BadGuy;
class Portable;
class Camera;
class PlayerStatus;
-class Player : public MovingObject, public UsesPhysic, public Scripting::Player, public ScriptInterface
+class Player : public MovingObject,
+ public Scripting::Player,
+ public ScriptInterface
{
public:
enum FallMode { ON_GROUND, JUMPING, TRAMPOLINE_JUMP, FALLING };
Controller* controller;
- CodeController* scripting_controller; /**< This controller is used when the Player is controlled via scripting */
+ std::auto_ptr<CodeController> scripting_controller; /**< This controller is used when the Player is controlled via scripting */
PlayerStatus* player_status;
bool duck;
bool dead;
Portable* get_grabbed_object() const
{
- return grabbed_object;
+ return grabbed_object;
}
void stop_grabbing()
{
*/
void stop_climbing(Climbable& climbable);
+ Physic& get_physic() { return physic; }
+
private:
void handle_input();
void handle_input_ghost(); /**< input handling while in ghost mode */
*/
void apply_friction();
+private:
+ Physic physic;
+
bool visible;
Portable* grabbed_object;
- Sprite* sprite; /**< The main sprite representing Tux */
- Sprite* smalltux_gameover;
- Sprite* smalltux_star;
- Sprite* bigtux_star;
+ std::auto_ptr<Sprite> sprite; /**< The main sprite representing Tux */
std::auto_ptr<Surface> airarrow; /**< arrow indicating Tux' position when he's above the camera */
unsigned int idle_stage;
Climbable* climbing; /**< Climbable object we are currently climbing, null if none */
+
+private:
+ Player(const Player&);
+ Player& operator=(const Player&);
};
#endif /*SUPERTUX_PLAYER_H*/
+
+/* EOF */
-// $Id$
-//
// SuperTux - PneumaticPlatform
// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "pneumatic_platform.hpp"
+#include "object/pneumatic_platform.hpp"
-#include <stdexcept>
-#include "log.hpp"
-#include "video/drawing_context.hpp"
-#include "resources.hpp"
-#include "player.hpp"
-#include "path.hpp"
-#include "path_walker.hpp"
-#include "sprite/sprite.hpp"
-#include "lisp/lisp.hpp"
-#include "object_factory.hpp"
-#include "sector.hpp"
+#include "object/player.hpp"
#include "object/portable.hpp"
+#include "supertux/object_factory.hpp"
+#include "supertux/sector.hpp"
-PneumaticPlatform::PneumaticPlatform(const lisp::Lisp& reader)
- : MovingSprite(reader, LAYER_OBJECTS, COLGROUP_STATIC),
- master(0), slave(0), start_y(0), offset_y(0), speed_y(0)
+PneumaticPlatform::PneumaticPlatform(const Reader& reader) :
+ MovingSprite(reader, LAYER_OBJECTS, COLGROUP_STATIC),
+ master(0),
+ slave(0),
+ start_y(0),
+ offset_y(0),
+ speed_y(0)
{
start_y = get_pos().y;
}
-PneumaticPlatform::PneumaticPlatform(PneumaticPlatform* master)
- : MovingSprite(*master),
- master(master), slave(this), start_y(master->start_y), offset_y(-master->offset_y), speed_y(0)
+PneumaticPlatform::PneumaticPlatform(PneumaticPlatform* master) :
+ MovingSprite(*master),
+ master(master),
+ slave(this),
+ start_y(master->start_y),
+ offset_y(-master->offset_y),
+ speed_y(0)
{
set_pos(get_pos() + Vector(master->get_bbox().get_width(), 0));
master->master = master;
master->slave = this;
}
-PneumaticPlatform::~PneumaticPlatform() {
+PneumaticPlatform::~PneumaticPlatform()
+{
if ((this == master) && (master)) {
slave->master = 0;
slave->slave = 0;
IMPLEMENT_FACTORY(PneumaticPlatform, "pneumatic-platform");
+/* EOF */
-// $Id$
-//
// SuperTux - PneumaticPlatform
// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __PNEUMATIC_PLATFORM_H__
-#define __PNEUMATIC_PLATFORM_H__
+#ifndef HEADER_SUPERTUX_OBJECT_PNEUMATIC_PLATFORM_HPP
+#define HEADER_SUPERTUX_OBJECT_PNEUMATIC_PLATFORM_HPP
-#include <memory>
-#include <string>
-#include <set>
#include "object/moving_sprite.hpp"
-#include "object/path.hpp"
-#include "object/path_walker.hpp"
/**
* Used to construct a pair of pneumatic platforms: If one is pushed down, the other one rises
class PneumaticPlatform : public MovingSprite
{
public:
- PneumaticPlatform(const lisp::Lisp& reader);
+ PneumaticPlatform(const Reader& reader);
PneumaticPlatform(PneumaticPlatform* master);
virtual ~PneumaticPlatform();
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __PORTABLE_H__
-#define __PORTABLE_H__
+#ifndef HEADER_SUPERTUX_OBJECT_PORTABLE_HPP
+#define HEADER_SUPERTUX_OBJECT_PORTABLE_HPP
-#include "moving_object.hpp"
-#include "direction.hpp"
-#include "refcounter.hpp"
+#include "supertux/direction.hpp"
+#include "supertux/moving_object.hpp"
+#include "util/refcounter.hpp"
/**
* An object that inherits from this object is considered "portable" and can
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <stdexcept>
-#include <math.h>
-#include <stdexcept>
-#include "powerup.hpp"
-#include "resources.hpp"
-#include "player.hpp"
#include "audio/sound_manager.hpp"
-#include "object_factory.hpp"
-#include "sector.hpp"
-#include "log.hpp"
+#include "object/player.hpp"
+#include "object/powerup.hpp"
+#include "supertux/object_factory.hpp"
+#include "supertux/sector.hpp"
+#include "util/reader.hpp"
-PowerUp::PowerUp(const lisp::Lisp& lisp)
- : MovingSprite(lisp, LAYER_OBJECTS, COLGROUP_MOVING)
+PowerUp::PowerUp(const Reader& lisp) :
+ MovingSprite(lisp, LAYER_OBJECTS, COLGROUP_MOVING)
{
lisp.get("script", script);
no_physics = false;
}
IMPLEMENT_FACTORY(PowerUp, "powerup");
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __POWERUP_H__
-#define __POWERUP_H__
+#ifndef HEADER_SUPERTUX_OBJECT_POWERUP_HPP
+#define HEADER_SUPERTUX_OBJECT_POWERUP_HPP
#include "object/moving_sprite.hpp"
-#include "lisp/lisp.hpp"
-#include "collision_hit.hpp"
-#include "physic.hpp"
-class PowerUp : public MovingSprite, private UsesPhysic
+class PowerUp : public MovingSprite
{
public:
- PowerUp(const lisp::Lisp& lisp);
+ PowerUp(const Reader& lisp);
virtual void update(float elapsed_time);
virtual void collision_solid(const CollisionHit& hit);
virtual HitResponse collision(GameObject& other, const CollisionHit& hit);
private:
+ Physic physic;
std::string script;
bool no_physics;
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux - Pulsing Light
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "pulsing_light.hpp"
-#include "video/color.hpp"
+#include "object/pulsing_light.hpp"
#include <math.h>
-#include "random_generator.hpp"
-PulsingLight::PulsingLight(const Vector& center, float cycle_len, float min_alpha, float max_alpha, const Color& color)
- : Light(center, color), min_alpha(min_alpha), max_alpha(max_alpha), cycle_len(cycle_len), t(0)
+#include "math/random_generator.hpp"
+
+PulsingLight::PulsingLight(const Vector& center, float cycle_len, float min_alpha, float max_alpha, const Color& color) :
+ Light(center, color),
+ min_alpha(min_alpha),
+ max_alpha(max_alpha),
+ cycle_len(cycle_len),
+ t(0)
{
assert(cycle_len > 0);
color = old_color;
}
+
+/* EOF */
-// $Id$
-//
// SuperTux - Pulsing Light
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __PULSING_LIGHT_HPP__
-#define __PULSING_LIGHT_HPP__
+#ifndef HEADER_SUPERTUX_OBJECT_PULSING_LIGHT_HPP
+#define HEADER_SUPERTUX_OBJECT_PULSING_LIGHT_HPP
-#include "light.hpp"
-#include "game_object.hpp"
-#include "lisp/lisp.hpp"
-#include "math/vector.hpp"
-#include "video/color.hpp"
+#include "object/light.hpp"
class Sprite;
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux - PushButton running a script
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
-#include <stdexcept>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "pushbutton.hpp"
-#include "object_factory.hpp"
-#include "player.hpp"
#include "audio/sound_manager.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "sector.hpp"
-#include "log.hpp"
+#include "object/player.hpp"
+#include "object/pushbutton.hpp"
#include "sprite/sprite.hpp"
+#include "supertux/object_factory.hpp"
+#include "supertux/sector.hpp"
namespace {
- const std::string BUTTON_SOUND = "sounds/switch.ogg";
- //14 -> 8
+const std::string BUTTON_SOUND = "sounds/switch.ogg";
+//14 -> 8
}
-PushButton::PushButton(const lisp::Lisp& lisp)
- : MovingSprite(lisp, "images/objects/pushbutton/pushbutton.sprite", LAYER_BACKGROUNDTILES+1, COLGROUP_MOVING), state(OFF)
+PushButton::PushButton(const Reader& lisp)
+ : MovingSprite(lisp, "images/objects/pushbutton/pushbutton.sprite", LAYER_BACKGROUNDTILES+1, COLGROUP_MOVING), state(OFF)
{
sound_manager->preload(BUTTON_SOUND);
set_action("off", -1);
{
Player* player = dynamic_cast<Player*>(&other);
if (!player) return FORCE_MOVE;
- float vy = player->physic.get_velocity_y();
+ float vy = player->get_physic().get_velocity_y();
//player->add_velocity(Vector(0, -150));
- player->physic.set_velocity_y(-150);
+ player->get_physic().set_velocity_y(-150);
if (state != OFF) return FORCE_MOVE;
if (!hit.top) return FORCE_MOVE;
}
IMPLEMENT_FACTORY(PushButton, "pushbutton");
+
+/* EOF */
-// $Id$
-//
// SuperTux - PushButton running a script
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef SUPERTUX_PUSHBUTTON_H
-#define SUPERTUX_PUSHBUTTON_H
+#ifndef HEADER_SUPERTUX_OBJECT_PUSHBUTTON_HPP
+#define HEADER_SUPERTUX_OBJECT_PUSHBUTTON_HPP
-#include "moving_sprite.hpp"
-#include "lisp/lisp.hpp"
+#include "object/moving_sprite.hpp"
/**
* PushButton - jump on it to run a script
class PushButton : public MovingSprite
{
public:
- PushButton(const lisp::Lisp& reader);
+ PushButton(const Reader& reader);
HitResponse collision(GameObject& other, const CollisionHit& hit);
void update(float elapsed_time);
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "rainsplash.hpp"
-#include "sector.hpp"
+#include "object/rainsplash.hpp"
RainSplash::RainSplash(Vector pos, bool vertical)
{
void
RainSplash::draw(DrawingContext& context)
{
- sprite->draw(context, position, LAYER_OBJECTS);
+ sprite->draw(context, position, LAYER_OBJECTS);
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#ifndef __RAINSPLASH_H__
-#define __RAINSPLASH_H__
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+#ifndef HEADER_SUPERTUX_OBJECT_RAINSPLASH_HPP
+#define HEADER_SUPERTUX_OBJECT_RAINSPLASH_HPP
-#include "game_object.hpp"
-#include "resources.hpp"
-#include "player.hpp"
#include "sprite/sprite.hpp"
#include "sprite/sprite_manager.hpp"
-#include "video/drawing_context.hpp"
+#include "supertux/game_object.hpp"
+
+class Player;
class RainSplash : public GameObject
{
virtual void update(float time);
virtual void draw(DrawingContext& context);
private:
- Sprite* sprite;
+ std::auto_ptr<Sprite> sprite;
Vector position;
int frame;
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "rock.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
#include "audio/sound_manager.hpp"
-#include "tile.hpp"
+#include "object/rock.hpp"
+#include "supertux/object_factory.hpp"
+#include "supertux/tile.hpp"
namespace {
- const std::string ROCK_SOUND = "sounds/brick.wav"; //TODO use own sound.
+const std::string ROCK_SOUND = "sounds/brick.wav"; //TODO use own sound.
}
-Rock::Rock(const Vector& pos, std::string spritename)
- : MovingSprite(pos, spritename)
+Rock::Rock(const Vector& pos, std::string spritename) :
+ MovingSprite(pos, spritename),
+ on_ground(),
+ grabbed(),
+ last_movement()
{
sound_manager->preload(ROCK_SOUND);
on_ground = false;
set_group(COLGROUP_MOVING_STATIC);
}
-Rock::Rock(const lisp::Lisp& reader)
- : MovingSprite(reader, "images/objects/rock/rock.sprite")
+Rock::Rock(const Reader& reader) :
+ MovingSprite(reader, "images/objects/rock/rock.sprite"),
+ on_ground(),
+ grabbed(),
+ last_movement()
{
sound_manager->preload(ROCK_SOUND);
on_ground = false;
set_group(COLGROUP_MOVING_STATIC);
}
-Rock::Rock(const lisp::Lisp& reader, std::string spritename)
+Rock::Rock(const Reader& reader, std::string spritename)
: MovingSprite(reader, spritename)
{
sound_manager->preload(ROCK_SOUND);
}
void
-Rock::write(lisp::Writer& writer)
-{
- writer.start_list("rock");
-
- writer.write("x", bbox.p1.x);
- writer.write("y", bbox.p1.y);
-
- writer.end_list("rock");
-}
-
-void
Rock::update(float elapsed_time)
{
if( grabbed )
}
IMPLEMENT_FACTORY(Rock, "rock");
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __ROCK_H__
-#define __ROCK_H__
+#ifndef HEADER_SUPERTUX_OBJECT_ROCK_HPP
+#define HEADER_SUPERTUX_OBJECT_ROCK_HPP
#include "object/moving_sprite.hpp"
-#include "physic.hpp"
-#include "portable.hpp"
-#include "serializable.hpp"
+#include "object/portable.hpp"
+#include "supertux/physic.hpp"
class Sprite;
-class Rock : public MovingSprite, public Portable, protected UsesPhysic, public Serializable
+class Rock : public MovingSprite,
+ public Portable
{
public:
Rock(const Vector& pos, std::string spritename);
- Rock(const lisp::Lisp& reader);
- Rock(const lisp::Lisp& reader, std::string spritename);
- virtual Rock* clone() const { return new Rock(*this); }
+ Rock(const Reader& reader);
+ Rock(const Reader& reader, std::string spritename);
void collision_solid(const CollisionHit& hit);
HitResponse collision(GameObject& other, const CollisionHit& hit);
void update(float elapsed_time);
- void write(lisp::Writer& writer);
void grab(MovingObject& object, const Vector& pos, Direction dir);
void ungrab(MovingObject& object, Direction dir);
protected:
+ Physic physic;
bool on_ground;
bool grabbed;
Vector last_movement;
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#include "object/scripted_object.hpp"
-#include <stdexcept>
-#include <math.h>
+#include <stdio.h>
-#include "scripted_object.hpp"
-#include "video/drawing_context.hpp"
#include "scripting/squirrel_util.hpp"
-#include "resources.hpp"
-#include "object_factory.hpp"
-#include "math/vector.hpp"
#include "sprite/sprite.hpp"
+#include "supertux/object_factory.hpp"
-ScriptedObject::ScriptedObject(const lisp::Lisp& lisp)
+ScriptedObject::ScriptedObject(const Reader& lisp)
: MovingSprite(lisp, LAYER_OBJECTS, COLGROUP_MOVING_STATIC),
solid(true), physic_enabled(true), visible(true), new_vel_set(false)
{
return solid;
}
-
void
ScriptedObject::set_action(const std::string& animation)
{
}
IMPLEMENT_FACTORY(ScriptedObject, "scriptedobject");
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __SCRIPTED_OBJECT_H__
-#define __SCRIPTED_OBJECT_H__
+#ifndef HEADER_SUPERTUX_OBJECT_SCRIPTED_OBJECT_HPP
+#define HEADER_SUPERTUX_OBJECT_SCRIPTED_OBJECT_HPP
-#include <string>
-#include "physic.hpp"
-#include "lisp/lisp.hpp"
#include "object/moving_sprite.hpp"
-#include "script_interface.hpp"
#include "scripting/scripted_object.hpp"
+#include "supertux/physic.hpp"
+#include "supertux/script_interface.hpp"
-class ScriptedObject : public MovingSprite, public UsesPhysic,
- public Scripting::ScriptedObject, public ScriptInterface
+class ScriptedObject : public MovingSprite,
+ public Scripting::ScriptedObject,
+ public ScriptInterface
{
public:
- ScriptedObject(const lisp::Lisp& lisp);
- virtual ScriptedObject* clone() const { return new ScriptedObject(*this); }
+ ScriptedObject(const Reader& lisp);
virtual void expose(HSQUIRRELVM vm, SQInteger table_idx);
virtual void unexpose(HSQUIRRELVM vm, SQInteger table_idx);
std::string get_name();
private:
+ Physic physic;
std::string name;
bool solid;
bool physic_enabled;
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "skull_tile.hpp"
-#include "lisp/lisp.hpp"
-#include "object_factory.hpp"
-#include "player.hpp"
-#include "sector.hpp"
-#include "resources.hpp"
+#include "math/random_generator.hpp"
+#include "object/player.hpp"
+#include "object/skull_tile.hpp"
#include "sprite/sprite.hpp"
-#include "random_generator.hpp"
+#include "supertux/object_factory.hpp"
+#include "supertux/sector.hpp"
static const float CRACKTIME = 0.3f;
static const float FALLTIME = 0.8f;
-SkullTile::SkullTile(const lisp::Lisp& lisp)
- : MovingSprite(lisp, "images/objects/skull_tile/skull_tile.sprite", LAYER_TILES, COLGROUP_STATIC), hit(false), falling(false)
+SkullTile::SkullTile(const Reader& lisp)
+ : MovingSprite(lisp, "images/objects/skull_tile/skull_tile.sprite", LAYER_TILES, COLGROUP_STATIC), hit(false), falling(false)
{
}
}
IMPLEMENT_FACTORY(SkullTile, "skull_tile");
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __SKULL_TILE_H__
-#define __SKULL_TILE_H__
+#ifndef HEADER_SUPERTUX_OBJECT_SKULL_TILE_HPP
+#define HEADER_SUPERTUX_OBJECT_SKULL_TILE_HPP
#include "object/moving_sprite.hpp"
-#include "physic.hpp"
-#include "timer.hpp"
class Player;
/** A tile that starts falling down if tux stands to long on it */
-class SkullTile : public MovingSprite, private UsesPhysic
+class SkullTile : public MovingSprite
{
public:
- SkullTile(const lisp::Lisp& lisp);
- virtual SkullTile* clone() const { return new SkullTile(*this); }
+ SkullTile(const Reader& lisp);
HitResponse collision(GameObject& other, const CollisionHit& hit);
void update(float elapsed_time);
void draw(DrawingContext& context);
private:
+ Physic physic;
Timer timer;
bool hit;
bool falling;
};
#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include "object/smoke_cloud.hpp"
+
+#include "sprite/sprite.hpp"
+#include "sprite/sprite_manager.hpp"
+
+SmokeCloud::SmokeCloud(const Vector& pos) :
+ position(pos)
+{
+ timer.start(.3f);
+ sprite = sprite_manager->create("images/objects/particles/stomp.sprite");
+}
+
+SmokeCloud::~SmokeCloud()
+{
+}
+
+void
+SmokeCloud::update(float elapsed_time)
+{
+ position.y -= 120 * elapsed_time;
+
+ if(timer.check())
+ remove_me();
+}
+
+void
+SmokeCloud::draw(DrawingContext& context)
+{
+ sprite->draw(context, position, LAYER_OBJECTS+1);
+}
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_OBJECT_SMOKE_CLOUD_HPP
+#define HEADER_SUPERTUX_OBJECT_SMOKE_CLOUD_HPP
+
+#include <memory>
+
+#include "math/vector.hpp"
+#include "supertux/game_object.hpp"
+#include "supertux/timer.hpp"
+#include "video/color.hpp"
+
+class Sprite;
+
+class SmokeCloud : public GameObject
+{
+public:
+ SmokeCloud(const Vector& pos);
+ ~SmokeCloud();
+
+ virtual void update(float elapsed_time);
+ virtual void draw(DrawingContext& context);
+
+private:
+ std::auto_ptr<Sprite> sprite;
+ Timer timer;
+ Vector position;
+
+private:
+ SmokeCloud(const SmokeCloud&);
+ SmokeCloud& operator=(const SmokeCloud&);
+};
+
+#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <math.h>
-#include "specialriser.hpp"
-#include "resources.hpp"
-#include "camera.hpp"
-#include "sector.hpp"
-#include "sprite/sprite_manager.hpp"
+#include "video/drawing_context.hpp"
+#include "object/specialriser.hpp"
+#include "supertux/sector.hpp"
SpecialRiser::SpecialRiser(Vector pos, MovingObject* _child)
: child(_child)
{
context.push_transform();
context.set_translation(
- context.get_translation() + Vector(0, -32 + offset));
+ context.get_translation() + Vector(0, -32 + offset));
child->draw(context);
context.pop_transform();
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __SPECIALRISE_H__
-#define __SPECIALRISE_H__
+#ifndef HEADER_SUPERTUX_OBJECT_SPECIALRISER_HPP
+#define HEADER_SUPERTUX_OBJECT_SPECIALRISER_HPP
-#include "moving_object.hpp"
+#include "supertux/moving_object.hpp"
/**
* special object that contains another object and slowly rises it out of a
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Ingo Ruhnke <grumbel@gmx.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "spotlight.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "resources.hpp"
-#include "video/drawing_context.hpp"
-#include "object_factory.hpp"
-#include "player.hpp"
-#include "sector.hpp"
+#include "object/spotlight.hpp"
#include "sprite/sprite.hpp"
-
-Spotlight::Spotlight(const lisp::Lisp& lisp)
- : angle(0.0f),
- color(1.0f, 1.0f, 1.0f)
+#include "sprite/sprite_manager.hpp"
+#include "supertux/object_factory.hpp"
+
+Spotlight::Spotlight(const Reader& lisp) :
+ position(),
+ angle(0.0f),
+ center(),
+ base(),
+ lights(),
+ light(),
+ lightcone(),
+ color(1.0f, 1.0f, 1.0f)
{
lisp.get("x", position.x);
lisp.get("y", position.y);
lightcone = sprite_manager->create("images/objects/spotlight/lightcone.sprite");
light = sprite_manager->create("images/objects/spotlight/light.sprite");
-
}
Spotlight::~Spotlight()
{
- delete center;
- delete base;
- delete lights;
- delete lightcone;
- delete light;
}
void
}
IMPLEMENT_FACTORY(Spotlight, "spotlight");
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_OBJECT_SPOTLIGHT_HPP
+#define HEADER_SUPERTUX_OBJECT_SPOTLIGHT_HPP
-#ifndef __SPOTLIGHT_HPP__
-#define __SPOTLIGHT_HPP__
+#include <memory>
-#include "game_object.hpp"
+#include "util/reader_fwd.hpp"
#include "math/vector.hpp"
-#include "lisp/lisp.hpp"
+#include "supertux/game_object.hpp"
#include "video/color.hpp"
class Sprite;
class Spotlight : public GameObject
{
public:
- Spotlight(const lisp::Lisp& reader);
+ Spotlight(const Reader& reader);
virtual ~Spotlight();
void update(float elapsed_time);
private:
Vector position;
float angle;
- Sprite* center;
- Sprite* base;
- Sprite* lights;
- Sprite* light;
- Sprite* lightcone;
+ std::auto_ptr<Sprite> center;
+ std::auto_ptr<Sprite> base;
+ std::auto_ptr<Sprite> lights;
+ std::auto_ptr<Sprite> light;
+ std::auto_ptr<Sprite> lightcone;
Color color;
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <stdexcept>
-#include "sprite_particle.hpp"
-#include "sector.hpp"
-#include "camera.hpp"
-#include "main.hpp"
-#include "log.hpp"
+#include "object/camera.hpp"
+#include "object/sprite_particle.hpp"
+#include "supertux/main.hpp"
+#include "supertux/sector.hpp"
-SpriteParticle::SpriteParticle(std::string sprite_name, std::string action, Vector position, AnchorPoint anchor, Vector velocity, Vector acceleration, int drawing_layer)
- : position(position), velocity(velocity), acceleration(acceleration), drawing_layer(drawing_layer)
+SpriteParticle::SpriteParticle(std::string sprite_name, std::string action,
+ Vector position, AnchorPoint anchor, Vector velocity, Vector acceleration,
+ int drawing_layer) :
+ position(position),
+ velocity(velocity),
+ acceleration(acceleration),
+ drawing_layer(drawing_layer)
{
sprite = sprite_manager->create(sprite_name);
- if (!sprite) throw std::runtime_error("Could not load sprite "+sprite_name);
+ if (!sprite.get()) throw std::runtime_error("Could not load sprite "+sprite_name);
sprite->set_action(action, 1);
sprite->set_animation_loops(1); //TODO: this is necessary because set_action will not set "loops" when "action" is the default action
void
SpriteParticle::draw(DrawingContext& context)
{
- sprite->draw(context, position, drawing_layer);
+ sprite->draw(context, position, drawing_layer);
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#ifndef __SPRITE_PARTICLE_H__
-#define __SPRITE_PARTICLE_H__
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+#ifndef HEADER_SUPERTUX_OBJECT_SPRITE_PARTICLE_HPP
+#define HEADER_SUPERTUX_OBJECT_SPRITE_PARTICLE_HPP
-#include "game_object.hpp"
-#include "resources.hpp"
-#include "player.hpp"
#include "object/anchor_point.hpp"
#include "sprite/sprite.hpp"
#include "sprite/sprite_manager.hpp"
-#include "video/drawing_context.hpp"
+
+class Player;
class SpriteParticle : public GameObject
{
virtual void hit(Player& player);
virtual void update(float elapsed_time);
virtual void draw(DrawingContext& context);
+
private:
- Sprite* sprite;
+ std::auto_ptr<Sprite> sprite;
Vector position;
Vector velocity;
Vector acceleration;
int drawing_layer;
+
+private:
+ SpriteParticle(const SpriteParticle&);
+ SpriteParticle& operator=(const SpriteParticle&);
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "star.hpp"
-#include "resources.hpp"
-#include "player.hpp"
-#include "player_status.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "video/drawing_context.hpp"
+#include "object/player.hpp"
+#include "object/star.hpp"
static const float INITIALJUMP = -400;
static const float SPEED = 150;
static const float JUMPSPEED = -300;
Star::Star(const Vector& pos, Direction direction)
- : MovingSprite(pos, "images/powerups/star/star.sprite", LAYER_OBJECTS, COLGROUP_MOVING)
+ : MovingSprite(pos, "images/powerups/star/star.sprite", LAYER_OBJECTS, COLGROUP_MOVING)
{
physic.set_velocity((direction == LEFT) ? -SPEED : SPEED, INITIALJUMP);
}
return FORCE_MOVE;
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __STAR_H__
-#define __STAR_H__
+#ifndef HEADER_SUPERTUX_OBJECT_STAR_HPP
+#define HEADER_SUPERTUX_OBJECT_STAR_HPP
#include "object/moving_sprite.hpp"
-#include "physic.hpp"
-#include "direction.hpp"
-class Star : public MovingSprite, private UsesPhysic
+class Star : public MovingSprite
{
public:
Star(const Vector& pos, Direction direction = RIGHT);
- virtual Star* clone() const { return new Star(*this); }
virtual void update(float elapsed_time);
virtual void collision_solid(const CollisionHit& hit);
virtual HitResponse collision(GameObject& other, const CollisionHit& hit);
+
+private:
+ Physic physic;
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "text_object.hpp"
+#include "object/text_object.hpp"
-#include <iostream>
-#include "resources.hpp"
-#include "main.hpp"
-#include "video/drawing_context.hpp"
#include "scripting/squirrel_util.hpp"
-#include "log.hpp"
+#include "supertux/main.hpp"
+#include "supertux/resources.hpp"
+#include "video/drawing_context.hpp"
-TextObject::TextObject(std::string name)
- : fading(0), fadetime(0), visible(false), anchor(ANCHOR_MIDDLE),
- pos(0, 0)
+TextObject::TextObject(std::string name) :
+ fading(0),
+ fadetime(0),
+ visible(false),
+ anchor(ANCHOR_MIDDLE),
+ pos(0, 0)
{
this->name = name;
font = normal_font;
float width = 500;
float height = 70;
Vector spos = pos + get_anchor_pos(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT),
- width, height, anchor);
+ width, height, anchor);
context.draw_filled_rect(spos, Vector(width, height),
- Color(0.6f, 0.7f, 0.8f, 0.5f), LAYER_GUI-50);
+ Color(0.6f, 0.7f, 0.8f, 0.5f), LAYER_GUI-50);
if (centered) {
context.draw_center_text(font, text, spos, LAYER_GUI-40, TextObject::default_color);
} else {
}
}
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __TEXTOBJECT_H__
-#define __TEXTOBJECT_H__
+#ifndef HEADER_SUPERTUX_OBJECT_TEXT_OBJECT_HPP
+#define HEADER_SUPERTUX_OBJECT_TEXT_OBJECT_HPP
-#include "game_object.hpp"
+#include "object/anchor_point.hpp"
#include "scripting/text.hpp"
-#include "script_interface.hpp"
-#include "anchor_point.hpp"
+#include "supertux/game_object.hpp"
+#include "supertux/script_interface.hpp"
#include "video/color.hpp"
class Font;
/** A text object intended for scripts that want to tell a story */
-class TextObject : public GameObject, public Scripting::Text,
+class TextObject : public GameObject,
+ public Scripting::Text,
public ScriptInterface
{
static Color default_color;
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux - Thunderstorm Game Object
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <config.h>
+#include "object/thunderstorm.hpp"
-#include "thunderstorm.hpp"
-#include "scripting/squirrel_util.hpp"
#include "audio/sound_manager.hpp"
-#include "video/drawing_context.hpp"
-#include "object_factory.hpp"
#include "object/electrifier.hpp"
-
-#include <stdexcept>
-#include <iostream>
-#include "main.hpp"
-#include "resources.hpp"
-#include "sector.hpp"
-#include "gettext.hpp"
-#include "object/player.hpp"
-#include "lisp/list_iterator.hpp"
-#include "log.hpp"
+#include "scripting/squirrel_util.hpp"
+#include "supertux/main.hpp"
+#include "supertux/object_factory.hpp"
+#include "supertux/sector.hpp"
+#include "util/reader.hpp"
namespace {
- const float LIGHTNING_DELAY = 2.0f;
- const float FLASH_DISPLAY_TIME = 0.1f;
+const float LIGHTNING_DELAY = 2.0f;
+const float FLASH_DISPLAY_TIME = 0.1f;
}
-Thunderstorm::Thunderstorm(const lisp::Lisp& reader)
- : running(true), interval(10.0f), layer(LAYER_BACKGROUNDTILES-1)
+Thunderstorm::Thunderstorm(const Reader& reader) :
+ running(true),
+ interval(10.0f),
+ layer(LAYER_BACKGROUNDTILES-1)
{
reader.get("name", name);
reader.get("running", running);
}
IMPLEMENT_FACTORY(Thunderstorm, "thunderstorm");
+
+/* EOF */
-// $Id$
-//
// SuperTux - Thunderstorm Game Object
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __THUNDERSTORM_H__
-#define __THUNDERSTORM_H__
+#ifndef HEADER_SUPERTUX_OBJECT_THUNDERSTORM_HPP
+#define HEADER_SUPERTUX_OBJECT_THUNDERSTORM_HPP
-#include "game_object.hpp"
-#include "timer.hpp"
-#include "lisp/lisp.hpp"
+#include "util/reader_fwd.hpp"
#include "scripting/thunderstorm.hpp"
-#include "script_interface.hpp"
+#include "supertux/game_object.hpp"
+#include "supertux/script_interface.hpp"
+#include "supertux/timer.hpp"
+#include "video/drawing_context.hpp"
/**
* Thunderstorm scriptable GameObject; plays thunder, lightning and electrifies water at regular interval
*/
-class Thunderstorm : public GameObject, public ScriptInterface
+class Thunderstorm : public GameObject,
+ public ScriptInterface
{
public:
- Thunderstorm(const lisp::Lisp& reader);
+ Thunderstorm(const Reader& reader);
- void update(float elapsed_time);
- void draw(DrawingContext& context);
+ void update(float elapsed_time);
+ void draw(DrawingContext& context);
- virtual void expose(HSQUIRRELVM vm, SQInteger table_idx);
- virtual void unexpose(HSQUIRRELVM vm, SQInteger table_idx);
+ virtual void expose(HSQUIRRELVM vm, SQInteger table_idx);
+ virtual void unexpose(HSQUIRRELVM vm, SQInteger table_idx);
- /**
- * @name Scriptable Methods
- * @{
- */
+ /**
+ * @name Scriptable Methods
+ * @{
+ */
- /**
- * Start playing thunder and lightning at configured interval
- */
- void start();
+ /**
+ * Start playing thunder and lightning at configured interval
+ */
+ void start();
- /**
- * Stop playing thunder and lightning at configured interval
- */
- void stop();
+ /**
+ * Stop playing thunder and lightning at configured interval
+ */
+ void stop();
- /**
- * Play thunder
- */
- void thunder();
+ /**
+ * Play thunder
+ */
+ void thunder();
- /**
- * Play lightning, i.e. call flash() and electrify()
- */
- void lightning();
+ /**
+ * Play lightning, i.e. call flash() and electrify()
+ */
+ void lightning();
- /**
- * Display a nice flash
- */
- void flash();
+ /**
+ * Display a nice flash
+ */
+ void flash();
- /**
- * Electrify water throughout the whole sector for a short time
- */
- void electrify();
+ /**
+ * Electrify water throughout the whole sector for a short time
+ */
+ void electrify();
- /**
- * @}
- */
+ /**
+ * @}
+ */
private:
- bool running; /**< whether we currently automatically trigger lightnings */
- float interval; /**< time between two lightnings */
- int layer; /**< layer, where flash will be painted */
+ bool running; /**< whether we currently automatically trigger lightnings */
+ float interval; /**< time between two lightnings */
+ int layer; /**< layer, where flash will be painted */
- Timer time_to_thunder; /**< counts down until next thunder */
- Timer time_to_lightning; /**< counts down until next lightning */
- Timer flash_display_timer; /**< counts down while flash is displayed */
+ Timer time_to_thunder; /**< counts down until next thunder */
+ Timer time_to_lightning; /**< counts down until next lightning */
+ Timer flash_display_timer; /**< counts down while flash is displayed */
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <cassert>
-#include <algorithm>
-#include <iostream>
-#include <stdexcept>
#include <math.h>
-#include <limits>
-
-#include "tilemap.hpp"
-#include "video/drawing_context.hpp"
-#include "level.hpp"
-#include "tile.hpp"
-#include "resources.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/list_iterator.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
-#include "main.hpp"
-#include "log.hpp"
-#include "tile_set.hpp"
-#include "tile_manager.hpp"
-#include "scripting/tilemap.hpp"
-#include "scripting/squirrel_util.hpp"
-TileMap::TileMap(const TileSet *new_tileset)
- : tileset(new_tileset), solid(false), speed_x(1), speed_y(1), width(0),
- height(0), z_pos(0), x_offset(0), y_offset(0), movement(Vector(0,0)), drawing_effect(NO_EFFECT),
- alpha(1.0), current_alpha(1.0), remaining_fade_time(0),
- draw_target(DrawingContext::NORMAL)
+#include "object/tilemap.hpp"
+#include "scripting/squirrel_util.hpp"
+#include "scripting/tilemap.hpp"
+#include "supertux/main.hpp"
+#include "supertux/object_factory.hpp"
+#include "supertux/tile_manager.hpp"
+#include "supertux/tile_set.hpp"
+#include "util/reader.hpp"
+
+TileMap::TileMap(const TileSet *new_tileset) :
+ tileset(new_tileset),
+ solid(false),
+ speed_x(1),
+ speed_y(1),
+ width(0),
+ height(0),
+ z_pos(0),
+ x_offset(0),
+ y_offset(0),
+ movement(Vector(0,0)),
+ drawing_effect(NO_EFFECT),
+ alpha(1.0),
+ current_alpha(1.0),
+ remaining_fade_time(0),
+ draw_target(DrawingContext::NORMAL)
{
}
-TileMap::TileMap(const lisp::Lisp& reader)
- : solid(false), speed_x(1), speed_y(1), width(-1),
- height(-1), z_pos(0), x_offset(0), y_offset(0), movement(Vector(0,0)), drawing_effect(NO_EFFECT),
- alpha(1.0), current_alpha(1.0), remaining_fade_time(0),
- draw_target(DrawingContext::NORMAL)
+TileMap::TileMap(const Reader& reader) :
+ solid(false),
+ speed_x(1),
+ speed_y(1),
+ width(-1),
+ height(-1),
+ z_pos(0),
+ x_offset(0),
+ y_offset(0),
+ movement(Vector(0,0)),
+ drawing_effect(NO_EFFECT),
+ alpha(1.0),
+ current_alpha(1.0),
+ remaining_fade_time(0),
+ draw_target(DrawingContext::NORMAL)
{
tileset = current_tileset;
assert(tileset != NULL);
}
TileMap::TileMap(const TileSet *new_tileset, std::string name, int z_pos,
- bool solid, size_t width, size_t height)
- : tileset(new_tileset), solid(solid), speed_x(1), speed_y(1), width(0),
- height(0), z_pos(z_pos), x_offset(0), y_offset(0), movement(Vector(0,0)),
- drawing_effect(NO_EFFECT), alpha(1.0), current_alpha(1.0),
- remaining_fade_time(0), draw_target(DrawingContext::NORMAL)
+ bool solid, size_t width, size_t height) :
+ tileset(new_tileset),
+ solid(solid),
+ speed_x(1),
+ speed_y(1),
+ width(0),
+ height(0),
+ z_pos(z_pos),
+ x_offset(0),
+ y_offset(0),
+ movement(Vector(0,0)),
+ drawing_effect(NO_EFFECT),
+ alpha(1.0),
+ current_alpha(1.0),
+ remaining_fade_time(0),
+ draw_target(DrawingContext::NORMAL)
{
this->name = name;
}
void
-TileMap::write(lisp::Writer& writer)
-{
- writer.start_list("tilemap");
-
- writer.write("z-pos", z_pos);
-
- writer.write("solid", solid);
- writer.write("speed", speed_x);
- writer.write("speed-y", speed_y);
- writer.write("width", width);
- writer.write("height", height);
- writer.write("tiles", tiles);
-
- writer.end_list("tilemap");
-}
-
-void
TileMap::update(float elapsed_time)
{
// handle tilemap fading
void
TileMap::set(int newwidth, int newheight, const std::vector<unsigned int>&newt,
- int new_z_pos, bool newsolid)
+ int new_z_pos, bool newsolid)
{
if(int(newt.size()) != newwidth * newheight)
throw std::runtime_error("Wrong tilecount count.");
return tiles[y*width + x];
}
-
const Tile*
TileMap::get_tile(int x, int y) const
{
this->remaining_fade_time = seconds;
}
-
void
TileMap::set_alpha(float alpha)
{
}
IMPLEMENT_FACTORY(TileMap, "tilemap");
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#ifndef SUPERTUX_TILEMAP_H
-#define SUPERTUX_TILEMAP_H
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <vector>
-#include <stdint.h>
-#include <string>
+#ifndef HEADER_SUPERTUX_OBJECT_TILEMAP_HPP
+#define HEADER_SUPERTUX_OBJECT_TILEMAP_HPP
-#include "game_object.hpp"
-#include "serializable.hpp"
-#include "math/vector.hpp"
-#include "video/drawing_context.hpp"
-#include "object/path.hpp"
#include "object/path_walker.hpp"
-#include "script_interface.hpp"
+#include "supertux/game_object.hpp"
+#include "supertux/script_interface.hpp"
+#include "video/drawing_context.hpp"
namespace lisp {
class Lisp;
/**
* This class is responsible for drawing the level tiles
*/
-class TileMap : public GameObject, public Serializable, public ScriptInterface
+class TileMap : public GameObject,
+ public ScriptInterface
{
public:
TileMap(const TileSet *tileset);
- TileMap(const lisp::Lisp& reader);
+ TileMap(const Reader& reader);
TileMap(const TileSet *tileset, std::string name, int z_pos, bool solid_,
size_t width_, size_t height_);
virtual ~TileMap();
- virtual void write(lisp::Writer& writer);
-
virtual void update(float elapsed_time);
virtual void draw(DrawingContext& context);
virtual void unexpose(HSQUIRRELVM vm, SQInteger table_idx);
void set(int width, int height, const std::vector<unsigned int>& vec,
- int z_pos, bool solid);
+ int z_pos, bool solid);
/** resizes the tilemap to a new width and height (tries to not destroy the
* existing map)
std::auto_ptr<PathWalker> walker;
DrawingContext::Target draw_target; /**< set to LIGHTMAP to draw to lightmap */
+
+private:
+ TileMap(const TileMap&);
+ TileMap& operator=(const TileMap&);
};
#endif /*SUPERTUX_TILEMAP_H*/
+
+/* EOF */
-// $Id$
-//
// SuperTux - Trampoline
// Copyright (C) 2006 Wolfgang Becker <uafr@gmx.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "trampoline.hpp"
-#include "object_factory.hpp"
-#include "player.hpp"
#include "audio/sound_manager.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "sprite/sprite.hpp"
#include "badguy/walking_badguy.hpp"
#include "control/controller.hpp"
+#include "object/player.hpp"
+#include "object/trampoline.hpp"
+#include "sprite/sprite.hpp"
+#include "sprite/sprite_manager.hpp"
+#include "supertux/object_factory.hpp"
/* Trampoline will accelerate player to to VY_INITIAL, if
* he jumps on it to VY_MIN. */
namespace {
- const std::string TRAMPOLINE_SOUND = "sounds/trampoline.wav";
- const float VY_MIN = -900; //negative, upwards
- const float VY_INITIAL = -500;
+const std::string TRAMPOLINE_SOUND = "sounds/trampoline.wav";
+const float VY_MIN = -900; //negative, upwards
+const float VY_INITIAL = -500;
}
-Trampoline::Trampoline(const lisp::Lisp& lisp)
- : Rock(lisp, "images/objects/trampoline/trampoline.sprite")
+Trampoline::Trampoline(const Reader& lisp)
+ : Rock(lisp, "images/objects/trampoline/trampoline.sprite")
{
sound_manager->preload(TRAMPOLINE_SOUND);
//Check if this trampoline is not portable
if(lisp.get("portable", portable)) {
if(!portable) {
- //we need another sprite
- sprite_name = "images/objects/trampoline/trampoline_fix.sprite";
- sprite = sprite_manager->create(sprite_name);
- sprite->set_action("normal");
+ //we need another sprite
+ sprite_name = "images/objects/trampoline/trampoline_fix.sprite";
+ sprite = sprite_manager->create(sprite_name);
+ sprite->set_action("normal");
}
}
}
Player* player = dynamic_cast<Player*> (&other);
//Trampoline works for player
if(player) {
- float vy = player->physic.get_velocity_y();
+ float vy = player->get_physic().get_velocity_y();
//player is falling down on trampoline
if(hit.top && vy >= 0) {
if(player->get_controller()->hold(Controller::JUMP)) {
} else {
vy = VY_INITIAL;
}
- player->physic.set_velocity_y(vy);
+ player->get_physic().set_velocity_y(vy);
sound_manager->play(TRAMPOLINE_SOUND);
sprite->set_action("swinging", 1);
return FORCE_MOVE;
}
IMPLEMENT_FACTORY(Trampoline, "trampoline");
+
+/* EOF */
-// $Id$
-//
// SuperTux - Trampoline
// Copyright (C) 2006 Wolfgang Becker <uafr@gmx.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef SUPERTUX_TRAMPOLINE_H
-#define SUPERTUX_TRAMPOLINE_H
+#ifndef HEADER_SUPERTUX_OBJECT_TRAMPOLINE_HPP
+#define HEADER_SUPERTUX_OBJECT_TRAMPOLINE_HPP
-#include "moving_sprite.hpp"
-#include "lisp/lisp.hpp"
#include "object/rock.hpp"
/**
class Trampoline : public Rock
{
public:
- Trampoline(const lisp::Lisp& reader);
+ Trampoline(const Reader& reader);
HitResponse collision(GameObject& other, const CollisionHit& hit);
void collision_solid(const CollisionHit& hit);
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux - Unstable Tile
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <config.h>
+#include "object/unstable_tile.hpp"
-#include "unstable_tile.hpp"
-#include "lisp/lisp.hpp"
-#include "object_factory.hpp"
-#include "player.hpp"
-#include "sector.hpp"
-#include "resources.hpp"
+#include "object/player.hpp"
#include "sprite/sprite.hpp"
-#include "random_generator.hpp"
-#include "object/bullet.hpp"
-#include "constants.hpp"
+#include "supertux/constants.hpp"
+#include "supertux/object_factory.hpp"
-UnstableTile::UnstableTile(const lisp::Lisp& lisp)
+UnstableTile::UnstableTile(const Reader& lisp)
: MovingSprite(lisp, LAYER_TILES, COLGROUP_STATIC), state(STATE_NORMAL)
{
sprite->set_action("normal");
if(state == STATE_NORMAL) {
Player* player = dynamic_cast<Player*> (&other);
if(player != NULL &&
- player->get_bbox().get_bottom() < get_bbox().get_top() + SHIFT_DELTA) {
+ player->get_bbox().get_bottom() < get_bbox().get_top() + SHIFT_DELTA) {
state = STATE_CRUMBLING;
sprite->set_action("crumbling", 1);
}
}
IMPLEMENT_FACTORY(UnstableTile, "unstable_tile");
+
+/* EOF */
-// $Id$
-//
// SuperTux - Unstable Tile
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __UNSTABLE_TILE_H__
-#define __UNSTABLE_TILE_H__
+#ifndef HEADER_SUPERTUX_OBJECT_UNSTABLE_TILE_HPP
+#define HEADER_SUPERTUX_OBJECT_UNSTABLE_TILE_HPP
#include "object/moving_sprite.hpp"
-#include "lisp/lisp.hpp"
-#include "physic.hpp"
-#include "timer.hpp"
+#include "supertux/physic.hpp"
+#include "supertux/timer.hpp"
/**
* A block that disintegrates when stood on
*/
-class UnstableTile : public MovingSprite, public UsesPhysic
+class UnstableTile : public MovingSprite
{
public:
- UnstableTile(const lisp::Lisp& lisp);
- virtual UnstableTile* clone() const { return new UnstableTile(*this); }
+ UnstableTile(const Reader& lisp);
HitResponse collision(GameObject& other, const CollisionHit& hit);
void update(float elapsed_time);
STATE_CRUMBLING, /**< crumbling, still solid */
STATE_DISINTEGRATING /**< disintegrating, no longer solid */
};
+
+private:
+ Physic physic;
State state;
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux - Weak Block
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "weak_block.hpp"
+#include "object/weak_block.hpp"
-#include "lisp/lisp.hpp"
-#include "object_factory.hpp"
-#include "player.hpp"
-#include "sector.hpp"
-#include "resources.hpp"
-#include "sprite/sprite.hpp"
-#include "random_generator.hpp"
#include "object/bullet.hpp"
+#include "supertux/object_factory.hpp"
+#include "supertux/sector.hpp"
#include <math.h>
-WeakBlock::WeakBlock(const lisp::Lisp& lisp)
+WeakBlock::WeakBlock(const Reader& lisp)
: MovingSprite(lisp, "images/objects/strawbox/strawbox.sprite", LAYER_TILES, COLGROUP_STATIC), state(STATE_NORMAL)
{
sprite->set_action("normal");
}
}
-
IMPLEMENT_FACTORY(WeakBlock, "weak_block");
+
+/* EOF */
-// $Id$
-//
// SuperTux - Weak Block
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __WEAK_BLOCK_H__
-#define __WEAK_BLOCK_H__
+#ifndef HEADER_SUPERTUX_OBJECT_WEAK_BLOCK_HPP
+#define HEADER_SUPERTUX_OBJECT_WEAK_BLOCK_HPP
#include "object/moving_sprite.hpp"
-#include "lisp/lisp.hpp"
-#include "physic.hpp"
-#include "timer.hpp"
+#include "supertux/physic.hpp"
/**
* A block that can be destroyed by Bullet hits
*/
-class WeakBlock : public MovingSprite, public UsesPhysic
+class WeakBlock : public MovingSprite
{
public:
- WeakBlock(const lisp::Lisp& lisp);
+ WeakBlock(const Reader& lisp);
HitResponse collision(GameObject& other, const CollisionHit& hit);
void update(float elapsed_time);
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux - Wind
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <config.h>
+#include "object/wind.hpp"
-#include "wind.hpp"
-#include "video/drawing_context.hpp"
+#include "math/random_generator.hpp"
+#include "object/particles.hpp"
#include "object/player.hpp"
-#include "object_factory.hpp"
-#include "random_generator.hpp"
-#include "sector.hpp"
-#include "particles.hpp"
-#include "scripting/wind.hpp"
#include "scripting/squirrel_util.hpp"
-#include "lisp/lisp.hpp"
+#include "scripting/wind.hpp"
+#include "supertux/object_factory.hpp"
+#include "supertux/sector.hpp"
+#include "util/reader.hpp"
+#include "video/drawing_context.hpp"
-Wind::Wind(const lisp::Lisp& reader)
+Wind::Wind(const Reader& reader)
: blowing(true), acceleration(100), elapsed_time(0)
{
reader.get("name", name);
// emit a particle
Vector ppos = Vector(systemRandom.randf(bbox.p1.x+8, bbox.p2.x-8), systemRandom.randf(bbox.p1.y+8, bbox.p2.y-8));
Vector pspeed = Vector(speed.x, speed.y);
- Sector::current()->add_object(new Particles(ppos, 44, 46, pspeed, Vector(0,0), 1, Color(.4f, .4f, .4f), 3, .1f, LAYER_BACKGROUNDTILES+1));
+ Sector::current()->add_object(new Particles(ppos, 44, 46, pspeed, Vector(0,0), 1, Color(.4f, .4f, .4f), 3, .1f,
+ LAYER_BACKGROUNDTILES+1));
}
}
}
IMPLEMENT_FACTORY(Wind, "wind");
+
+/* EOF */
-// $Id$
-//
// SuperTux - Wind
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#ifndef SUPERTUX_WIND_H
-#define SUPERTUX_WIND_H
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "moving_object.hpp"
-#include "script_interface.hpp"
+#ifndef HEADER_SUPERTUX_OBJECT_WIND_HPP
+#define HEADER_SUPERTUX_OBJECT_WIND_HPP
-#include <set>
+#include "supertux/moving_object.hpp"
+#include "supertux/script_interface.hpp"
+#include "util/reader_fwd.hpp"
class Player;
-namespace lisp {
-class Lisp;
-}
/**
* Defines an area that will gently push Players in one direction
*/
-class Wind : public MovingObject, public ScriptInterface
+class Wind : public MovingObject,
+ public ScriptInterface
{
public:
- Wind(const lisp::Lisp& reader);
+ Wind(const Reader& reader);
void update(float elapsed_time);
void draw(DrawingContext& context);
};
#endif
+
+/* EOF */
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Ricardo Cruz <rick2@aeiou.pt>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include <config.h>
-
-#include <sstream>
-#include <stdexcept>
-
-#include "lisp/lisp.hpp"
-#include "lisp/parser.hpp"
-#include "object_factory.hpp"
-#include "math/vector.hpp"
-
-GameObject* create_object(const std::string& name, const lisp::Lisp& reader)
-{
- Factory::Factories::iterator i = Factory::get_factories().find(name);
- if(i == Factory::get_factories().end()) {
- std::stringstream msg;
- msg << "No factory for object '" << name << "' found.";
- throw std::runtime_error(msg.str());
- }
-
- return i->second->create_object(reader);
-}
-
-GameObject* create_object(const std::string& name, const Vector& pos, const Direction dir)
-{
- std::stringstream lisptext;
- lisptext << "((x " << pos.x << ")"
- << " (y " << pos.y << ")";
- if(dir != AUTO)
- lisptext << " (direction " << dir << "))";
-
- lisp::Parser parser;
- const lisp::Lisp* lisp = parser.parse(lisptext, "create_object");
- GameObject* object = create_object(name, *(lisp->get_car()));
-
- return object;
-}
-
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Ricardo Cruz <rick2@aeiou.pt>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#ifndef OBJECT_FACTORY_H
-#define OBJECT_FACTORY_H
-
-#include <string>
-#include <map>
-
-#include "direction.hpp"
-
-namespace lisp { class Lisp; }
-class Vector;
-class GameObject;
-
-class Factory
-{
-public:
- virtual ~Factory()
- { }
-
- /** Creates a new gameobject from a lisp node.
- * Remember to delete the objects later
- */
- virtual GameObject* create_object(const lisp::Lisp& reader) = 0;
-
- typedef std::map<std::string, Factory*> Factories;
- static Factories &get_factories()
- {
- static Factories object_factories;
- return object_factories;
- }
-};
-
-GameObject* create_object(const std::string& name, const lisp::Lisp& reader);
-GameObject* create_object(const std::string& name, const Vector& pos, const Direction dir = AUTO);
-
-/** comment from Matze:
- * Yes I know macros are evil, but in this specific case they save
- * A LOT of typing and evil code duplication.
- * I'll happily accept alternatives if someone can present me one that does
- * not involve typing 4 or more lines for each object class
- */
-#define IMPLEMENT_FACTORY(CLASS, NAME) \
-class INTERN_##CLASS##Factory : public Factory \
-{ \
-public: \
- INTERN_##CLASS##Factory() \
- { \
- get_factories()[NAME] = this; \
- } \
- \
- ~INTERN_##CLASS##Factory() \
- { \
- get_factories().erase(NAME); \
- } \
- \
- virtual GameObject* create_object(const lisp::Lisp& reader) \
- { \
- return new CLASS(reader); \
- } \
-}; \
-static INTERN_##CLASS##Factory factory_##CLASS;
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-
-#ifndef __OBJECT_REMOVE_LISTENER_H__
-#define __OBJECT_REMOVE_LISTENER_H__
-
-class GameObject;
-
-class ObjectRemoveListener
-{
-public:
- virtual ~ObjectRemoveListener()
- {}
-
- virtual void object_removed(GameObject* object) = 0;
-};
-
-#endif
+++ /dev/null
-/* obstack.c - subroutines used implicitly by object stack macros
- Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C 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.
-
- The GNU C 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 the GNU C Library; if not, write to the Free
- Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA. */
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include "obstack.h"
-
-/* NOTE BEFORE MODIFYING THIS FILE: This version number must be
- incremented whenever callers compiled using an old obstack.h can no
- longer properly call the functions in this obstack.c. */
-#define OBSTACK_INTERFACE_VERSION 1
-
-#include <stdio.h> /* Random thing to get __GNU_LIBRARY__. */
-#include <stddef.h>
-#include <stdint.h>
-
-/* Determine default alignment. */
-union fooround
-{
- uintmax_t i;
- long double d;
- void *p;
-};
-struct fooalign
-{
- char c;
- union fooround u;
-};
-/* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT.
- But in fact it might be less smart and round addresses to as much as
- DEFAULT_ROUNDING. So we prepare for it to do that. */
-enum
- {
- DEFAULT_ALIGNMENT = offsetof (struct fooalign, u),
- DEFAULT_ROUNDING = sizeof (union fooround)
- };
-
-/* When we copy a long block of data, this is the unit to do it with.
- On some machines, copying successive ints does not work;
- in such a case, redefine COPYING_UNIT to `long' (if that works)
- or `char' as a last resort. */
-# ifndef COPYING_UNIT
-# define COPYING_UNIT int
-# endif
-
-
-/* The functions allocating more room by calling `obstack_chunk_alloc'
- jump to the handler pointed to by `obstack_alloc_failed_handler'.
- This can be set to a user defined function which should either
- abort gracefully or use longjump - but shouldn't return. This
- variable by default points to the internal function
- `print_and_abort'. */
-static void print_and_abort (void);
-void (*obstack_alloc_failed_handler) (void) = print_and_abort;
-
-/* Exit value used when `print_and_abort' is used. */
-# include <stdlib.h>
-int obstack_exit_failure = EXIT_FAILURE;
-
-/* Define a macro that either calls functions with the traditional malloc/free
- calling interface, or calls functions with the mmalloc/mfree interface
- (that adds an extra first argument), based on the state of use_extra_arg.
- For free, do not use ?:, since some compilers, like the MIPS compilers,
- do not allow (expr) ? void : void. */
-
-# define CALL_CHUNKFUN(h, size) \
- (((h) -> use_extra_arg) \
- ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
- : (*(struct _obstack_chunk *(*) (long)) (h)->chunkfun) ((size)))
-
-# define CALL_FREEFUN(h, old_chunk) \
- do { \
- if ((h) -> use_extra_arg) \
- (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
- else \
- (*(void (*) (void *)) (h)->freefun) ((old_chunk)); \
- } while (0)
-
-/* Initialize an obstack H for use. Specify chunk size SIZE (0 means default).
- Objects start on multiples of ALIGNMENT (0 means use default).
- CHUNKFUN is the function to use to allocate chunks,
- and FREEFUN the function to free them.
-
- Return nonzero if successful, calls obstack_alloc_failed_handler if
- allocation fails. */
-
-int
-_obstack_begin (struct obstack *h,
- int size, int alignment,
- void *(*chunkfun) (long),
- void (*freefun) (void *))
-{
- register struct _obstack_chunk *chunk; /* points to new chunk */
-
- if (alignment == 0)
- alignment = DEFAULT_ALIGNMENT;
- if (size == 0)
- /* Default size is what GNU malloc can fit in a 4096-byte block. */
- {
- /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
- Use the values for range checking, because if range checking is off,
- the extra bytes won't be missed terribly, but if range checking is on
- and we used a larger request, a whole extra 4096 bytes would be
- allocated.
-
- These number are irrelevant to the new GNU malloc. I suspect it is
- less sensitive to the size of the request. */
- int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
- + 4 + DEFAULT_ROUNDING - 1)
- & ~(DEFAULT_ROUNDING - 1));
- size = 4096 - extra;
- }
-
- h->chunkfun = (struct _obstack_chunk * (*)(void *, long)) chunkfun;
- h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
- h->chunk_size = size;
- h->alignment_mask = alignment - 1;
- h->use_extra_arg = 0;
-
- chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
- if (!chunk)
- (*obstack_alloc_failed_handler) ();
- h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents,
- alignment - 1);
- h->chunk_limit = chunk->limit
- = (char *) chunk + h->chunk_size;
- chunk->prev = 0;
- /* The initial chunk now contains no empty object. */
- h->maybe_empty_object = 0;
- h->alloc_failed = 0;
- return 1;
-}
-
-int
-_obstack_begin_1 (struct obstack *h, int size, int alignment,
- void *(*chunkfun) (void *, long),
- void (*freefun) (void *, void *),
- void *arg)
-{
- register struct _obstack_chunk *chunk; /* points to new chunk */
-
- if (alignment == 0)
- alignment = DEFAULT_ALIGNMENT;
- if (size == 0)
- /* Default size is what GNU malloc can fit in a 4096-byte block. */
- {
- /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
- Use the values for range checking, because if range checking is off,
- the extra bytes won't be missed terribly, but if range checking is on
- and we used a larger request, a whole extra 4096 bytes would be
- allocated.
-
- These number are irrelevant to the new GNU malloc. I suspect it is
- less sensitive to the size of the request. */
- int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
- + 4 + DEFAULT_ROUNDING - 1)
- & ~(DEFAULT_ROUNDING - 1));
- size = 4096 - extra;
- }
-
- h->chunkfun = (struct _obstack_chunk * (*)(void *,long)) chunkfun;
- h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
- h->chunk_size = size;
- h->alignment_mask = alignment - 1;
- h->extra_arg = arg;
- h->use_extra_arg = 1;
-
- chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
- if (!chunk)
- (*obstack_alloc_failed_handler) ();
- h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents,
- alignment - 1);
- h->chunk_limit = chunk->limit
- = (char *) chunk + h->chunk_size;
- chunk->prev = 0;
- /* The initial chunk now contains no empty object. */
- h->maybe_empty_object = 0;
- h->alloc_failed = 0;
- return 1;
-}
-
-/* Allocate a new current chunk for the obstack *H
- on the assumption that LENGTH bytes need to be added
- to the current object, or a new object of length LENGTH allocated.
- Copies any partial object from the end of the old chunk
- to the beginning of the new one. */
-
-void
-_obstack_newchunk (struct obstack *h, int length)
-{
- register struct _obstack_chunk *old_chunk = h->chunk;
- register struct _obstack_chunk *new_chunk;
- register long new_size;
- register long obj_size = h->next_free - h->object_base;
- register long i;
- long already;
- char *object_base;
-
- /* Compute size for new chunk. */
- new_size = (obj_size + length) + (obj_size >> 3) + h->alignment_mask + 100;
- if (new_size < h->chunk_size)
- new_size = h->chunk_size;
-
- /* Allocate and initialize the new chunk. */
- new_chunk = CALL_CHUNKFUN (h, new_size);
- if (!new_chunk)
- (*obstack_alloc_failed_handler) ();
- h->chunk = new_chunk;
- new_chunk->prev = old_chunk;
- new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;
-
- /* Compute an aligned object_base in the new chunk */
- object_base =
- __PTR_ALIGN ((char *) new_chunk, new_chunk->contents, h->alignment_mask);
-
- /* Move the existing object to the new chunk.
- Word at a time is fast and is safe if the object
- is sufficiently aligned. */
- if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT)
- {
- for (i = obj_size / sizeof (COPYING_UNIT) - 1;
- i >= 0; i--)
- ((COPYING_UNIT *)object_base)[i]
- = ((COPYING_UNIT *)h->object_base)[i];
- /* We used to copy the odd few remaining bytes as one extra COPYING_UNIT,
- but that can cross a page boundary on a machine
- which does not do strict alignment for COPYING_UNITS. */
- already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT);
- }
- else
- already = 0;
- /* Copy remaining bytes one by one. */
- for (i = already; i < obj_size; i++)
- object_base[i] = h->object_base[i];
-
- /* If the object just copied was the only data in OLD_CHUNK,
- free that chunk and remove it from the chain.
- But not if that chunk might contain an empty object. */
- if (! h->maybe_empty_object
- && (h->object_base
- == __PTR_ALIGN ((char *) old_chunk, old_chunk->contents,
- h->alignment_mask)))
- {
- new_chunk->prev = old_chunk->prev;
- CALL_FREEFUN (h, old_chunk);
- }
-
- h->object_base = object_base;
- h->next_free = h->object_base + obj_size;
- /* The new chunk certainly contains no empty object yet. */
- h->maybe_empty_object = 0;
-}
-
-/* Return nonzero if object OBJ has been allocated from obstack H.
- This is here for debugging.
- If you use it in a program, you are probably losing. */
-
-/* Suppress -Wmissing-prototypes warning. We don't want to declare this in
- obstack.h because it is just for debugging. */
-int _obstack_allocated_p (struct obstack *h, void *obj);
-
-int
-_obstack_allocated_p (struct obstack *h, void *obj)
-{
- register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
- register struct _obstack_chunk *plp; /* point to previous chunk if any */
-
- lp = (h)->chunk;
- /* We use >= rather than > since the object cannot be exactly at
- the beginning of the chunk but might be an empty object exactly
- at the end of an adjacent chunk. */
- while (lp != 0 && ((void *) lp >= obj || (void *) (lp)->limit < obj))
- {
- plp = lp->prev;
- lp = plp;
- }
- return lp != 0;
-}
-
-/* Free objects in obstack H, including OBJ and everything allocate
- more recently than OBJ. If OBJ is zero, free everything in H. */
-
-# undef obstack_free
-
-void
-obstack_free (struct obstack *h, void *obj)
-{
- register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
- register struct _obstack_chunk *plp; /* point to previous chunk if any */
-
- lp = h->chunk;
- /* We use >= because there cannot be an object at the beginning of a chunk.
- But there can be an empty object at that address
- at the end of another chunk. */
- while (lp != 0 && ((void *) lp >= obj || (void *) (lp)->limit < obj))
- {
- plp = lp->prev;
- CALL_FREEFUN (h, lp);
- lp = plp;
- /* If we switch chunks, we can't tell whether the new current
- chunk contains an empty object, so assume that it may. */
- h->maybe_empty_object = 1;
- }
- if (lp)
- {
- h->object_base = h->next_free = (char *) (obj);
- h->chunk_limit = lp->limit;
- h->chunk = lp;
- }
- else if (obj != 0)
- /* obj is not in any of the chunks! */
- abort ();
-}
-
-int
-_obstack_memory_used (struct obstack *h)
-{
- register struct _obstack_chunk* lp;
- register int nbytes = 0;
-
- for (lp = h->chunk; lp != 0; lp = lp->prev)
- {
- nbytes += lp->limit - (char *) lp;
- }
- return nbytes;
-}
-
-static void
-__attribute__ ((noreturn))
-print_and_abort (void)
-{
- /* Don't change any of these strings. Yes, it would be possible to add
- the newline to the string and use fputs or so. But this must not
- happen because the "memory exhausted" message appears in other places
- like this and the translation should be reused instead of creating
- a very similar string which requires a separate translation. */
- fprintf (stderr, "%s\n", "memory exhausted");
- exit (obstack_exit_failure);
-}
-
+++ /dev/null
-/* obstack.h - object stack macros
- Copyright (C) 1988-1994,1996-1999,2003,2004,2005
- Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C 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.
-
- The GNU C 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 the GNU C Library; if not, write to the Free
- Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA. */
-
-/* Summary:
-
-All the apparent functions defined here are macros. The idea
-is that you would use these pre-tested macros to solve a
-very specific set of problems, and they would run fast.
-Caution: no side-effects in arguments please!! They may be
-evaluated MANY times!!
-
-These macros operate a stack of objects. Each object starts life
-small, and may grow to maturity. (Consider building a word syllable
-by syllable.) An object can move while it is growing. Once it has
-been "finished" it never changes address again. So the "top of the
-stack" is typically an immature growing object, while the rest of the
-stack is of mature, fixed size and fixed address objects.
-
-These routines grab large chunks of memory, using a function you
-supply, called `obstack_chunk_alloc'. On occasion, they free chunks,
-by calling `obstack_chunk_free'. You must define them and declare
-them before using any obstack macros.
-
-Each independent stack is represented by a `struct obstack'.
-Each of the obstack macros expects a pointer to such a structure
-as the first argument.
-
-One motivation for this package is the problem of growing char strings
-in symbol tables. Unless you are "fascist pig with a read-only mind"
---Gosper's immortal quote from HAKMEM item 154, out of context--you
-would not like to put any arbitrary upper limit on the length of your
-symbols.
-
-In practice this often means you will build many short symbols and a
-few long symbols. At the time you are reading a symbol you don't know
-how long it is. One traditional method is to read a symbol into a
-buffer, realloc()ating the buffer every time you try to read a symbol
-that is longer than the buffer. This is beaut, but you still will
-want to copy the symbol from the buffer to a more permanent
-symbol-table entry say about half the time.
-
-With obstacks, you can work differently. Use one obstack for all symbol
-names. As you read a symbol, grow the name in the obstack gradually.
-When the name is complete, finalize it. Then, if the symbol exists already,
-free the newly read name.
-
-The way we do this is to take a large chunk, allocating memory from
-low addresses. When you want to build a symbol in the chunk you just
-add chars above the current "high water mark" in the chunk. When you
-have finished adding chars, because you got to the end of the symbol,
-you know how long the chars are, and you can create a new object.
-Mostly the chars will not burst over the highest address of the chunk,
-because you would typically expect a chunk to be (say) 100 times as
-long as an average object.
-
-In case that isn't clear, when we have enough chars to make up
-the object, THEY ARE ALREADY CONTIGUOUS IN THE CHUNK (guaranteed)
-so we just point to it where it lies. No moving of chars is
-needed and this is the second win: potentially long strings need
-never be explicitly shuffled. Once an object is formed, it does not
-change its address during its lifetime.
-
-When the chars burst over a chunk boundary, we allocate a larger
-chunk, and then copy the partly formed object from the end of the old
-chunk to the beginning of the new larger chunk. We then carry on
-accreting characters to the end of the object as we normally would.
-
-A special macro is provided to add a single char at a time to a
-growing object. This allows the use of register variables, which
-break the ordinary 'growth' macro.
-
-Summary:
- We allocate large chunks.
- We carve out one object at a time from the current chunk.
- Once carved, an object never moves.
- We are free to append data of any size to the currently
- growing object.
- Exactly one object is growing in an obstack at any one time.
- You can run one obstack per control block.
- You may have as many control blocks as you dare.
- Because of the way we do it, you can `unwind' an obstack
- back to a previous state. (You may remove objects much
- as you would with a stack.)
-*/
-
-
-/* Don't do the contents of this file more than once. */
-
-#ifndef _OBSTACK_H
-#define _OBSTACK_H 1
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* We need the type of a pointer subtraction. If __PTRDIFF_TYPE__ is
- defined, as with GNU C, use that; that way we don't pollute the
- namespace with <stddef.h>'s symbols. Otherwise, include <stddef.h>
- and use ptrdiff_t. */
-
-#ifdef __PTRDIFF_TYPE__
-# define PTR_INT_TYPE __PTRDIFF_TYPE__
-#else
-# include <stddef.h>
-# define PTR_INT_TYPE ptrdiff_t
-#endif
-
-/* If B is the base of an object addressed by P, return the result of
- aligning P to the next multiple of A + 1. B and P must be of type
- char *. A + 1 must be a power of 2. */
-
-#define __BPTR_ALIGN(B, P, A) ((B) + (((P) - (B) + (A)) & ~(A)))
-
-/* Similar to _BPTR_ALIGN (B, P, A), except optimize the common case
- where pointers can be converted to integers, aligned as integers,
- and converted back again. If PTR_INT_TYPE is narrower than a
- pointer (e.g., the AS/400), play it safe and compute the alignment
- relative to B. Otherwise, use the faster strategy of computing the
- alignment relative to 0. */
-
-#define __PTR_ALIGN(B, P, A) \
- __BPTR_ALIGN (sizeof (PTR_INT_TYPE) < sizeof (void *) ? (B) : (char *) 0, \
- P, A)
-
-#include <string.h>
-
-struct _obstack_chunk /* Lives at front of each chunk. */
-{
- char *limit; /* 1 past end of this chunk */
- struct _obstack_chunk *prev; /* address of prior chunk or NULL */
- char contents[4]; /* objects begin here */
-};
-
-struct obstack /* control current object in current chunk */
-{
- long chunk_size; /* preferred size to allocate chunks in */
- struct _obstack_chunk *chunk; /* address of current struct obstack_chunk */
- char *object_base; /* address of object we are building */
- char *next_free; /* where to add next char to current object */
- char *chunk_limit; /* address of char after current chunk */
- union
- {
- PTR_INT_TYPE tempint;
- void *tempptr;
- } temp; /* Temporary for some macros. */
- int alignment_mask; /* Mask of alignment for each object. */
- /* These prototypes vary based on `use_extra_arg', and we use
- casts to the prototypeless function type in all assignments,
- but having prototypes here quiets -Wstrict-prototypes. */
- struct _obstack_chunk *(*chunkfun) (void *, long);
- void (*freefun) (void *, struct _obstack_chunk *);
- void *extra_arg; /* first arg for chunk alloc/dealloc funcs */
- unsigned use_extra_arg:1; /* chunk alloc/dealloc funcs take extra arg */
- unsigned maybe_empty_object:1;/* There is a possibility that the current
- chunk contains a zero-length object. This
- prevents freeing the chunk if we allocate
- a bigger chunk to replace it. */
- unsigned alloc_failed:1; /* No longer used, as we now call the failed
- handler on error, but retained for binary
- compatibility. */
-};
-
-/* Declare the external functions we use; they are in obstack.c. */
-
-extern void _obstack_newchunk (struct obstack *, int);
-extern int _obstack_begin (struct obstack *, int, int,
- void *(*) (long), void (*) (void *));
-extern int _obstack_begin_1 (struct obstack *, int, int,
- void *(*) (void *, long),
- void (*) (void *, void *), void *);
-extern int _obstack_memory_used (struct obstack *);
-
-void obstack_free (struct obstack *obstack, void *block);
-
-
-/* Error handler called when `obstack_chunk_alloc' failed to allocate
- more memory. This can be set to a user defined function which
- should either abort gracefully or use longjump - but shouldn't
- return. The default action is to print a message and abort. */
-extern void (*obstack_alloc_failed_handler) (void);
-
-/* Exit value used when `print_and_abort' is used. */
-extern int obstack_exit_failure;
-
-/* Pointer to beginning of object being allocated or to be allocated next.
- Note that this might not be the final address of the object
- because a new chunk might be needed to hold the final size. */
-
-#define obstack_base(h) ((void *) (h)->object_base)
-
-/* Size for allocating ordinary chunks. */
-
-#define obstack_chunk_size(h) ((h)->chunk_size)
-
-/* Pointer to next byte not yet allocated in current chunk. */
-
-#define obstack_next_free(h) ((h)->next_free)
-
-/* Mask specifying low bits that should be clear in address of an object. */
-
-#define obstack_alignment_mask(h) ((h)->alignment_mask)
-
-/* To prevent prototype warnings provide complete argument list. */
-#define obstack_init(h) \
- _obstack_begin ((h), 0, 0, \
- (void *(*) (long)) obstack_chunk_alloc, \
- (void (*) (void *)) obstack_chunk_free)
-
-#define obstack_begin(h, size) \
- _obstack_begin ((h), (size), 0, \
- (void *(*) (long)) obstack_chunk_alloc, \
- (void (*) (void *)) obstack_chunk_free)
-
-#define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \
- _obstack_begin ((h), (size), (alignment), \
- (void *(*) (long)) (chunkfun), \
- (void (*) (void *)) (freefun))
-
-#define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \
- _obstack_begin_1 ((h), (size), (alignment), \
- (void *(*) (void *, long)) (chunkfun), \
- (void (*) (void *, void *)) (freefun), (arg))
-
-#define obstack_chunkfun(h, newchunkfun) \
- ((h) -> chunkfun = (struct _obstack_chunk *(*)(void *, long)) (newchunkfun))
-
-#define obstack_freefun(h, newfreefun) \
- ((h) -> freefun = (void (*)(void *, struct _obstack_chunk *)) (newfreefun))
-
-#define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = (achar))
-
-#define obstack_blank_fast(h,n) ((h)->next_free += (n))
-
-#define obstack_memory_used(h) _obstack_memory_used (h)
-
-#if defined __GNUC__ && defined __STDC__ && __STDC__
-/* NextStep 2.0 cc is really gcc 1.93 but it defines __GNUC__ = 2 and
- does not implement __extension__. But that compiler doesn't define
- __GNUC_MINOR__. */
-# if __GNUC__ < 2 || (__NeXT__ && !__GNUC_MINOR__)
-# define __extension__
-# endif
-
-/* For GNU C, if not -traditional,
- we can define these macros to compute all args only once
- without using a global variable.
- Also, we can avoid using the `temp' slot, to make faster code. */
-
-# define obstack_object_size(OBSTACK) \
- __extension__ \
- ({ struct obstack const *__o = (OBSTACK); \
- (unsigned) (__o->next_free - __o->object_base); })
-
-# define obstack_room(OBSTACK) \
- __extension__ \
- ({ struct obstack const *__o = (OBSTACK); \
- (unsigned) (__o->chunk_limit - __o->next_free); })
-
-# define obstack_make_room(OBSTACK,length) \
-__extension__ \
-({ struct obstack *__o = (OBSTACK); \
- int __len = (length); \
- if (__o->chunk_limit - __o->next_free < __len) \
- _obstack_newchunk (__o, __len); \
- (void) 0; })
-
-# define obstack_empty_p(OBSTACK) \
- __extension__ \
- ({ struct obstack const *__o = (OBSTACK); \
- (__o->chunk->prev == 0 \
- && __o->next_free == __PTR_ALIGN ((char *) __o->chunk, \
- __o->chunk->contents, \
- __o->alignment_mask)); })
-
-# define obstack_grow(OBSTACK,where,length) \
-__extension__ \
-({ struct obstack *__o = (OBSTACK); \
- int __len = (length); \
- if (__o->next_free + __len > __o->chunk_limit) \
- _obstack_newchunk (__o, __len); \
- memcpy (__o->next_free, where, __len); \
- __o->next_free += __len; \
- (void) 0; })
-
-# define obstack_grow0(OBSTACK,where,length) \
-__extension__ \
-({ struct obstack *__o = (OBSTACK); \
- int __len = (length); \
- if (__o->next_free + __len + 1 > __o->chunk_limit) \
- _obstack_newchunk (__o, __len + 1); \
- memcpy (__o->next_free, where, __len); \
- __o->next_free += __len; \
- *(__o->next_free)++ = 0; \
- (void) 0; })
-
-# define obstack_1grow(OBSTACK,datum) \
-__extension__ \
-({ struct obstack *__o = (OBSTACK); \
- if (__o->next_free + 1 > __o->chunk_limit) \
- _obstack_newchunk (__o, 1); \
- obstack_1grow_fast (__o, datum); \
- (void) 0; })
-
-/* These assume that the obstack alignment is good enough for pointers
- or ints, and that the data added so far to the current object
- shares that much alignment. */
-
-# define obstack_ptr_grow(OBSTACK,datum) \
-__extension__ \
-({ struct obstack *__o = (OBSTACK); \
- if (__o->next_free + sizeof (void *) > __o->chunk_limit) \
- _obstack_newchunk (__o, sizeof (void *)); \
- obstack_ptr_grow_fast (__o, datum); }) \
-
-# define obstack_int_grow(OBSTACK,datum) \
-__extension__ \
-({ struct obstack *__o = (OBSTACK); \
- if (__o->next_free + sizeof (int) > __o->chunk_limit) \
- _obstack_newchunk (__o, sizeof (int)); \
- obstack_int_grow_fast (__o, datum); })
-
-# define obstack_ptr_grow_fast(OBSTACK,aptr) \
-__extension__ \
-({ struct obstack *__o1 = (OBSTACK); \
- *(const void **) __o1->next_free = (aptr); \
- __o1->next_free += sizeof (const void *); \
- (void) 0; })
-
-# define obstack_int_grow_fast(OBSTACK,aint) \
-__extension__ \
-({ struct obstack *__o1 = (OBSTACK); \
- *(int *) __o1->next_free = (aint); \
- __o1->next_free += sizeof (int); \
- (void) 0; })
-
-# define obstack_blank(OBSTACK,length) \
-__extension__ \
-({ struct obstack *__o = (OBSTACK); \
- int __len = (length); \
- if (__o->chunk_limit - __o->next_free < __len) \
- _obstack_newchunk (__o, __len); \
- obstack_blank_fast (__o, __len); \
- (void) 0; })
-
-# define obstack_alloc(OBSTACK,length) \
-__extension__ \
-({ struct obstack *__h = (OBSTACK); \
- obstack_blank (__h, (length)); \
- obstack_finish (__h); })
-
-# define obstack_copy(OBSTACK,where,length) \
-__extension__ \
-({ struct obstack *__h = (OBSTACK); \
- obstack_grow (__h, (where), (length)); \
- obstack_finish (__h); })
-
-# define obstack_copy0(OBSTACK,where,length) \
-__extension__ \
-({ struct obstack *__h = (OBSTACK); \
- obstack_grow0 (__h, (where), (length)); \
- obstack_finish (__h); })
-
-/* The local variable is named __o1 to avoid a name conflict
- when obstack_blank is called. */
-# define obstack_finish(OBSTACK) \
-__extension__ \
-({ struct obstack *__o1 = (OBSTACK); \
- void *__value = (void *) __o1->object_base; \
- if (__o1->next_free == __value) \
- __o1->maybe_empty_object = 1; \
- __o1->next_free \
- = __PTR_ALIGN (__o1->object_base, __o1->next_free, \
- __o1->alignment_mask); \
- if (__o1->next_free - (char *)__o1->chunk \
- > __o1->chunk_limit - (char *)__o1->chunk) \
- __o1->next_free = __o1->chunk_limit; \
- __o1->object_base = __o1->next_free; \
- __value; })
-
-# define obstack_free(OBSTACK, OBJ) \
-__extension__ \
-({ struct obstack *__o = (OBSTACK); \
- void *__obj = (OBJ); \
- if (__obj > (void *)__o->chunk && __obj < (void *)__o->chunk_limit) \
- __o->next_free = __o->object_base = (char *)__obj; \
- else (obstack_free) (__o, __obj); })
-
-#else /* not __GNUC__ or not __STDC__ */
-
-# define obstack_object_size(h) \
- (unsigned) ((h)->next_free - (h)->object_base)
-
-# define obstack_room(h) \
- (unsigned) ((h)->chunk_limit - (h)->next_free)
-
-# define obstack_empty_p(h) \
- ((h)->chunk->prev == 0 \
- && (h)->next_free == __PTR_ALIGN ((char *) (h)->chunk, \
- (h)->chunk->contents, \
- (h)->alignment_mask))
-
-/* Note that the call to _obstack_newchunk is enclosed in (..., 0)
- so that we can avoid having void expressions
- in the arms of the conditional expression.
- Casting the third operand to void was tried before,
- but some compilers won't accept it. */
-
-# define obstack_make_room(h,length) \
-( (h)->temp.tempint = (length), \
- (((h)->next_free + (h)->temp.tempint > (h)->chunk_limit) \
- ? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0))
-
-# define obstack_grow(h,where,length) \
-( (h)->temp.tempint = (length), \
- (((h)->next_free + (h)->temp.tempint > (h)->chunk_limit) \
- ? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0), \
- memcpy ((h)->next_free, where, (h)->temp.tempint), \
- (h)->next_free += (h)->temp.tempint)
-
-# define obstack_grow0(h,where,length) \
-( (h)->temp.tempint = (length), \
- (((h)->next_free + (h)->temp.tempint + 1 > (h)->chunk_limit) \
- ? (_obstack_newchunk ((h), (h)->temp.tempint + 1), 0) : 0), \
- memcpy ((h)->next_free, where, (h)->temp.tempint), \
- (h)->next_free += (h)->temp.tempint, \
- *((h)->next_free)++ = 0)
-
-# define obstack_1grow(h,datum) \
-( (((h)->next_free + 1 > (h)->chunk_limit) \
- ? (_obstack_newchunk ((h), 1), 0) : 0), \
- obstack_1grow_fast (h, datum))
-
-# define obstack_ptr_grow(h,datum) \
-( (((h)->next_free + sizeof (char *) > (h)->chunk_limit) \
- ? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0), \
- obstack_ptr_grow_fast (h, datum))
-
-# define obstack_int_grow(h,datum) \
-( (((h)->next_free + sizeof (int) > (h)->chunk_limit) \
- ? (_obstack_newchunk ((h), sizeof (int)), 0) : 0), \
- obstack_int_grow_fast (h, datum))
-
-# define obstack_ptr_grow_fast(h,aptr) \
- (((const void **) ((h)->next_free += sizeof (void *)))[-1] = (aptr))
-
-# define obstack_int_grow_fast(h,aint) \
- (((int *) ((h)->next_free += sizeof (int)))[-1] = (aint))
-
-# define obstack_blank(h,length) \
-( (h)->temp.tempint = (length), \
- (((h)->chunk_limit - (h)->next_free < (h)->temp.tempint) \
- ? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0), \
- obstack_blank_fast (h, (h)->temp.tempint))
-
-# define obstack_alloc(h,length) \
- (obstack_blank ((h), (length)), obstack_finish ((h)))
-
-# define obstack_copy(h,where,length) \
- (obstack_grow ((h), (where), (length)), obstack_finish ((h)))
-
-# define obstack_copy0(h,where,length) \
- (obstack_grow0 ((h), (where), (length)), obstack_finish ((h)))
-
-# define obstack_finish(h) \
-( ((h)->next_free == (h)->object_base \
- ? (((h)->maybe_empty_object = 1), 0) \
- : 0), \
- (h)->temp.tempptr = (h)->object_base, \
- (h)->next_free \
- = __PTR_ALIGN ((h)->object_base, (h)->next_free, \
- (h)->alignment_mask), \
- (((h)->next_free - (char *) (h)->chunk \
- > (h)->chunk_limit - (char *) (h)->chunk) \
- ? ((h)->next_free = (h)->chunk_limit) : 0), \
- (h)->object_base = (h)->next_free, \
- (h)->temp.tempptr)
-
-# define obstack_free(h,obj) \
-( (h)->temp.tempint = (char *) (obj) - (char *) (h)->chunk, \
- ((((h)->temp.tempint > 0 \
- && (h)->temp.tempint < (h)->chunk_limit - (char *) (h)->chunk)) \
- ? (int) ((h)->next_free = (h)->object_base \
- = (h)->temp.tempint + (char *) (h)->chunk) \
- : (((obstack_free) ((h), (h)->temp.tempint + (char *) (h)->chunk), 0), 0)))
-
-#endif /* not __GNUC__ or not __STDC__ */
-
-#ifdef __cplusplus
-} /* C++ */
-#endif
-
-#endif /* obstack.h */
-// $Id$
-//
// SuperTux
// Copyright (C) 2007 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-#ifndef OBSTACKPP_H_
-#define OBSTACKPP_H_
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_OBSTACK_OBSTACKPP_HPP
+#define HEADER_SUPERTUX_OBSTACK_OBSTACKPP_HPP
-#include "obstack.h"
+#include <obstack.h>
inline void*
operator new (size_t bytes, struct obstack& obst)
#endif
+/* EOF */
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Tobas Glaesser <tobi.web@gmx.de>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include <config.h>
-
-#include "profile_menu.hpp"
-#include "options_menu.hpp"
-#include "gui/menu.hpp"
-#include "audio/sound_manager.hpp"
-#include "control/joystickkeyboardcontroller.hpp"
-#include "main.hpp"
-#include "gettext.hpp"
-#include "video/renderer.hpp"
-#include "gameconfig.hpp"
-
-Menu* options_menu = 0;
-
-enum OptionsMenuIDs {
- MNID_FULLSCREEN,
- MNID_FULLSCREEN_RESOLUTION,
- MNID_MAGNIFICATION,
- MNID_ASPECTRATIO,
- MNID_PROFILES,
- MNID_SOUND,
- MNID_MUSIC
-};
-
-class LanguageMenu : public Menu
-{
-public:
- LanguageMenu() {
- add_label(_("Language"));
- add_hl();
- add_entry(0, std::string("<")+_("auto-detect")+">");
- add_entry(1, "English");
-
- int mnid = 10;
- std::set<std::string> languages = dictionary_manager.get_languages();
- for (std::set<std::string>::iterator i = languages.begin(); i != languages.end(); i++) {
- std::string locale_name = *i;
- TinyGetText::LanguageDef ldef = TinyGetText::get_language_def(locale_name);
- std::string locale_fullname = locale_name;
- if (std::string(ldef.code) == locale_name) {
- locale_fullname = ldef.name;
- }
- add_entry(mnid++, locale_fullname);
- }
-
- add_hl();
- add_back(_("Back"));
- }
-
- virtual void menu_action(MenuItem* item) {
- if (item->id == 0) {
- config->locale = "";
- dictionary_manager.set_language(config->locale);
- config->save();
- Menu::pop_current();
- }
- else if (item->id == 1) {
- config->locale = "en";
- dictionary_manager.set_language(config->locale);
- config->save();
- Menu::pop_current();
- }
- int mnid = 10;
- std::set<std::string> languages = dictionary_manager.get_languages();
- for (std::set<std::string>::iterator i = languages.begin(); i != languages.end(); i++) {
- std::string locale_name = *i;
- if (item->id == mnid++) {
- config->locale = locale_name;
- dictionary_manager.set_language(config->locale);
- config->save();
- Menu::pop_current();
- }
- }
- }
-};
-
-
-class OptionsMenu : public Menu
-{
-public:
- OptionsMenu();
- virtual ~OptionsMenu();
-
- virtual void menu_action(MenuItem* item);
-
-protected:
- std::auto_ptr<LanguageMenu> language_menu;
-
-};
-
-OptionsMenu::OptionsMenu()
-{
- language_menu.reset(new LanguageMenu());
-
- add_label(_("Options"));
- add_hl();
-
- // Language change should only be possible in the main menu, since elsewhere it might not always work fully
- // FIXME: Implement me: if (get_parent() == main_menu)
- add_submenu(_("Select Language"), language_menu.get())
- ->set_help(_("Select a different language to display text in"));
-
- add_submenu(_("Select Profile"), get_profile_menu())
- ->set_help(_("Select a profile to play with"));
-
- add_toggle(MNID_PROFILES, _("Profile on Startup"), config->sound_enabled)
- ->set_help(_("Select your profile immediately after start-up"));
-
- add_toggle(MNID_FULLSCREEN,_("Fullscreen"), config->use_fullscreen)
- ->set_help(_("Fill the entire screen"));
-
- MenuItem* fullscreen_res = add_string_select(MNID_FULLSCREEN_RESOLUTION, _("Resolution"));
- fullscreen_res->set_help(_("Determine the resolution used in fullscreen mode (you must toggle fullscreen to complete the change)"));
-
- MenuItem* magnification = add_string_select(MNID_MAGNIFICATION, _("Magnification"));
- magnification->set_help(_("Change the magnification of the game area"));
-
- // These values go from screen:640/projection:1600 to
- // screen:1600/projection:640 (i.e. 640, 800, 1024, 1280, 1600)
- magnification->list.push_back("auto");
- magnification->list.push_back("40%");
- magnification->list.push_back("50%");
- magnification->list.push_back("62.5%");
- magnification->list.push_back("80%");
- magnification->list.push_back("100%");
- magnification->list.push_back("125%");
- magnification->list.push_back("160%");
- magnification->list.push_back("200%");
- magnification->list.push_back("250%");
-
- SDL_Rect** modes = SDL_ListModes(NULL, SDL_FULLSCREEN|SDL_OPENGL);
-
- if (modes == (SDL_Rect **)0)
- { // No resolutions at all available, bad
-
- }
- else if(modes == (SDL_Rect **)-1)
- { // All resolutions should work, so we fall back to hardcoded defaults
- fullscreen_res->list.push_back("640x480");
- fullscreen_res->list.push_back("800x600");
- fullscreen_res->list.push_back("1024x768");
- fullscreen_res->list.push_back("1152x864");
- fullscreen_res->list.push_back("1280x960");
- fullscreen_res->list.push_back("1280x1024");
- fullscreen_res->list.push_back("1440x900");
- fullscreen_res->list.push_back("1680x1050");
- fullscreen_res->list.push_back("1600x1200");
- fullscreen_res->list.push_back("1920x1080");
- fullscreen_res->list.push_back("1920x1200");
- }
- else
- {
- for(int i = 0; modes[i]; ++i)
- {
- std::ostringstream out;
- out << modes[i]->w << "x" << modes[i]->h;
- fullscreen_res->list.push_back(out.str());
- }
- }
-
- MenuItem* aspect = add_string_select(MNID_ASPECTRATIO, _("Aspect Ratio"));
- aspect->set_help(_("Adjust the aspect ratio"));
-
- aspect->list.push_back("auto");
- aspect->list.push_back("5:4");
- aspect->list.push_back("4:3");
- aspect->list.push_back("16:10");
- aspect->list.push_back("16:9");
- aspect->list.push_back("1368:768");
-
- if (config->aspect_width != 0 && config->aspect_height != 0)
- {
- std::ostringstream out;
- out << config->aspect_width << ":" << config->aspect_height;
- std::string aspect_ratio = out.str();
- for(std::vector<std::string>::iterator i = aspect->list.begin(); i != aspect->list.end(); ++i)
- {
- if(*i == aspect_ratio)
- {
- aspect_ratio.clear();
- break;
- }
- }
-
- if (!aspect_ratio.empty())
- {
- aspect->selected = aspect->list.size();
- aspect->list.push_back(aspect_ratio);
- }
- }
-
- if (sound_manager->is_audio_enabled()) {
- add_toggle(MNID_SOUND, _("Sound"), config->sound_enabled)
- ->set_help(_("Disable all sound effects"));
- add_toggle(MNID_MUSIC, _("Music"), config->music_enabled)
- ->set_help(_("Disable all music"));
- } else {
- add_inactive(MNID_SOUND, _("Sound (disabled)"));
- add_inactive(MNID_MUSIC, _("Music (disabled)"));
- }
-
- add_submenu(_("Setup Keyboard"), main_controller->get_key_options_menu())
- ->set_help(_("Configure key-action mappings"));
-
- add_submenu(_("Setup Joystick"),main_controller->get_joystick_options_menu())
- ->set_help(_("Configure joystick control-action mappings"));
- add_hl();
- add_back(_("Back"));
-}
-
-OptionsMenu::~OptionsMenu()
-{
-}
-
-void
-OptionsMenu::menu_action(MenuItem* item)
-{
- switch (item->id) {
- case MNID_ASPECTRATIO:
- {
- if (item->list[item->selected] == "auto")
- {
- config->aspect_width = 0; // Magic values
- config->aspect_height = 0;
- Renderer::instance()->apply_config();
- Menu::recalc_pos();
- }
- else if(sscanf(item->list[item->selected].c_str(), "%d:%d", &config->aspect_width, &config->aspect_height) == 2)
- {
- Renderer::instance()->apply_config();
- Menu::recalc_pos();
- }
- else
- {
- assert(!"This must not be reached");
- }
- }
- break;
-
- case MNID_MAGNIFICATION:
- if (item->list[item->selected] == "auto")
- {
- config->magnification = 0.0f; // Magic value
- }
- else if(sscanf(item->list[item->selected].c_str(), "%f", &config->magnification) == 1)
- {
- config->magnification /= 100.0f;
- }
- Renderer::instance()->apply_config();
- Menu::recalc_pos();
- break;
-
- case MNID_FULLSCREEN_RESOLUTION:
- if(sscanf(item->list[item->selected].c_str(), "%dx%d", &config->fullscreen_width, &config->fullscreen_height) == 2)
- {
- // do nothing, changes are only applied when toggling fullscreen mode
- }
- break;
-
- case MNID_FULLSCREEN:
- if(config->use_fullscreen != options_menu->is_toggled(MNID_FULLSCREEN)) {
- config->use_fullscreen = !config->use_fullscreen;
- init_video(); // FIXME: Should call apply_config instead
- Menu::recalc_pos();
- config->save();
- }
- break;
-
- case MNID_SOUND:
- if(config->sound_enabled != options_menu->is_toggled(MNID_SOUND)) {
- config->sound_enabled = !config->sound_enabled;
- sound_manager->enable_sound(config->sound_enabled);
- config->save();
- }
- break;
-
- case MNID_MUSIC:
- if(config->music_enabled != options_menu->is_toggled(MNID_MUSIC)) {
- config->music_enabled = !config->music_enabled;
- sound_manager->enable_music(config->music_enabled);
- config->save();
- }
- break;
-
- default:
- break;
- }
-}
-
-Menu* get_options_menu()
-{
- //static OptionsMenu menu;
- options_menu = new OptionsMenu();
- return options_menu;
-}
-
-void free_options_menu()
-{
- delete options_menu;
- options_menu = 0;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Tobas Glaesser <tobi.web@gmx.de>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#ifndef __OPTIONS_MENU_HPP__
-#define __OPTIONS_MENU_HPP__
-
-class Menu;
-Menu* get_options_menu();
-void free_options_menu();
-
-#endif
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "physfs_sdl.hpp"
+#include "physfs/physfs_sdl.hpp"
#include <physfs.h>
-
-#include <stdexcept>
#include <sstream>
-#include <iostream>
-
+#include <stdexcept>
#include <assert.h>
-#include "log.hpp"
+
+#include "util/log.hpp"
static int funcSeek(struct SDL_RWops* context, int offset, int whence)
{
- PHYSFS_file* file = (PHYSFS_file*) context->hidden.unknown.data1;
- int res;
- switch(whence) {
- case SEEK_SET:
- res = PHYSFS_seek(file, offset);
- break;
- case SEEK_CUR:
- res = PHYSFS_seek(file, PHYSFS_tell(file) + offset);
- break;
- case SEEK_END:
- res = PHYSFS_seek(file, PHYSFS_fileLength(file) + offset);
- break;
- default:
- res = 0;
- assert(false);
- break;
- }
- if(res == 0) {
- log_warning << "Error seeking in file: " << PHYSFS_getLastError() << std::endl;
- return -1;
- }
+ PHYSFS_file* file = (PHYSFS_file*) context->hidden.unknown.data1;
+ int res;
+ switch(whence) {
+ case SEEK_SET:
+ res = PHYSFS_seek(file, offset);
+ break;
+ case SEEK_CUR:
+ res = PHYSFS_seek(file, PHYSFS_tell(file) + offset);
+ break;
+ case SEEK_END:
+ res = PHYSFS_seek(file, PHYSFS_fileLength(file) + offset);
+ break;
+ default:
+ res = 0;
+ assert(false);
+ break;
+ }
+ if(res == 0) {
+ log_warning << "Error seeking in file: " << PHYSFS_getLastError() << std::endl;
+ return -1;
+ }
- return (int) PHYSFS_tell(file);
+ return (int) PHYSFS_tell(file);
}
static int funcRead(struct SDL_RWops* context, void* ptr, int size, int maxnum)
{
- PHYSFS_file* file = (PHYSFS_file*) context->hidden.unknown.data1;
+ PHYSFS_file* file = (PHYSFS_file*) context->hidden.unknown.data1;
- int res = PHYSFS_read(file, ptr, size, maxnum);
- return res;
+ int res = PHYSFS_read(file, ptr, size, maxnum);
+ return res;
}
static int funcClose(struct SDL_RWops* context)
{
- PHYSFS_file* file = (PHYSFS_file*) context->hidden.unknown.data1;
+ PHYSFS_file* file = (PHYSFS_file*) context->hidden.unknown.data1;
- PHYSFS_close(file);
- delete context;
+ PHYSFS_close(file);
+ delete context;
- return 0;
+ return 0;
}
SDL_RWops* get_physfs_SDLRWops(const std::string& filename)
{
- // check this as PHYSFS seems to be buggy and still returns a
- // valid pointer in this case
- if(filename == "") {
- throw std::runtime_error("Couldn't open file: empty filename");
- }
+ // check this as PHYSFS seems to be buggy and still returns a
+ // valid pointer in this case
+ if(filename == "") {
+ throw std::runtime_error("Couldn't open file: empty filename");
+ }
- PHYSFS_file* file = (PHYSFS_file*) PHYSFS_openRead(filename.c_str());
- if(!file) {
- std::stringstream msg;
- msg << "Couldn't open '" << filename << "': "
- << PHYSFS_getLastError();
- throw std::runtime_error(msg.str());
- }
+ PHYSFS_file* file = (PHYSFS_file*) PHYSFS_openRead(filename.c_str());
+ if(!file) {
+ std::stringstream msg;
+ msg << "Couldn't open '" << filename << "': "
+ << PHYSFS_getLastError();
+ throw std::runtime_error(msg.str());
+ }
- SDL_RWops* ops = new SDL_RWops();
- ops->type = 0;
- ops->hidden.unknown.data1 = file;
- ops->seek = funcSeek;
- ops->read = funcRead;
- ops->write = 0;
- ops->close = funcClose;
- return ops;
+ SDL_RWops* ops = new SDL_RWops();
+ ops->type = 0;
+ ops->hidden.unknown.data1 = file;
+ ops->seek = funcSeek;
+ ops->read = funcRead;
+ ops->write = 0;
+ ops->close = funcClose;
+ return ops;
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __PHYSFSSDL_HPP__
-#define __PHYSFSSDL_HPP__
+#ifndef HEADER_SUPERTUX_PHYSFS_PHYSFS_SDL_HPP
+#define HEADER_SUPERTUX_PHYSFS_PHYSFS_SDL_HPP
#include <SDL.h>
#include <string>
SDL_RWops* get_physfs_SDLRWops(const std::string& filename);
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <config.h>
+#include "physfs/physfs_stream.hpp"
-#include "physfs_stream.hpp"
+#include <config.h>
#include <assert.h>
-#include <physfs.h>
-#include <stdexcept>
#include <sstream>
+#include <stdexcept>
IFileStreambuf::IFileStreambuf(const std::string& filename)
{
- // check this as PHYSFS seems to be buggy and still returns a
- // valid pointer in this case
- if(filename == "") {
- throw std::runtime_error("Couldn't open file: empty filename");
- }
- file = PHYSFS_openRead(filename.c_str());
- if(file == 0) {
- std::stringstream msg;
- msg << "Couldn't open file '" << filename << "': "
- << PHYSFS_getLastError();
- throw std::runtime_error(msg.str());
- }
+ // check this as PHYSFS seems to be buggy and still returns a
+ // valid pointer in this case
+ if(filename == "") {
+ throw std::runtime_error("Couldn't open file: empty filename");
+ }
+ file = PHYSFS_openRead(filename.c_str());
+ if(file == 0) {
+ std::stringstream msg;
+ msg << "Couldn't open file '" << filename << "': "
+ << PHYSFS_getLastError();
+ throw std::runtime_error(msg.str());
+ }
}
IFileStreambuf::~IFileStreambuf()
{
- PHYSFS_close(file);
+ PHYSFS_close(file);
}
int
IFileStreambuf::underflow()
{
- if(PHYSFS_eof(file)) {
- return traits_type::eof();
- }
+ if(PHYSFS_eof(file)) {
+ return traits_type::eof();
+ }
- PHYSFS_sint64 bytesread = PHYSFS_read(file, buf, 1, sizeof(buf));
- if(bytesread <= 0) {
- return traits_type::eof();
- }
- setg(buf, buf, buf + bytesread);
+ PHYSFS_sint64 bytesread = PHYSFS_read(file, buf, 1, sizeof(buf));
+ if(bytesread <= 0) {
+ return traits_type::eof();
+ }
+ setg(buf, buf, buf + bytesread);
- return buf[0];
+ return buf[0];
}
IFileStreambuf::pos_type
OFileStreambuf::OFileStreambuf(const std::string& filename)
{
- file = PHYSFS_openWrite(filename.c_str());
- if(file == 0) {
- std::stringstream msg;
- msg << "Couldn't open file '" << filename << "': "
- << PHYSFS_getLastError();
- throw std::runtime_error(msg.str());
- }
-
- setp(buf, buf+sizeof(buf));
+ file = PHYSFS_openWrite(filename.c_str());
+ if(file == 0) {
+ std::stringstream msg;
+ msg << "Couldn't open file '" << filename << "': "
+ << PHYSFS_getLastError();
+ throw std::runtime_error(msg.str());
+ }
+
+ setp(buf, buf+sizeof(buf));
}
OFileStreambuf::~OFileStreambuf()
{
- sync();
- PHYSFS_close(file);
+ sync();
+ PHYSFS_close(file);
}
int
OFileStreambuf::overflow(int c)
{
- char c2 = (char)c;
+ char c2 = (char)c;
- if(pbase() == pptr())
- return 0;
+ if(pbase() == pptr())
+ return 0;
- size_t size = pptr() - pbase();
- PHYSFS_sint64 res = PHYSFS_write(file, pbase(), 1, size);
- if(res <= 0)
- return traits_type::eof();
+ size_t size = pptr() - pbase();
+ PHYSFS_sint64 res = PHYSFS_write(file, pbase(), 1, size);
+ if(res <= 0)
+ return traits_type::eof();
- if(c != traits_type::eof()) {
- PHYSFS_sint64 res = PHYSFS_write(file, &c2, 1, 1);
- if(res <= 0)
- return traits_type::eof();
- }
+ if(c != traits_type::eof()) {
+ PHYSFS_sint64 res = PHYSFS_write(file, &c2, 1, 1);
+ if(res <= 0)
+ return traits_type::eof();
+ }
- setp(buf, buf + res);
- return 0;
+ setp(buf, buf + res);
+ return 0;
}
int
OFileStreambuf::sync()
{
- return overflow(traits_type::eof());
+ return overflow(traits_type::eof());
}
//---------------------------------------------------------------------------
IFileStream::IFileStream(const std::string& filename)
- : std::istream(new IFileStreambuf(filename))
+ : std::istream(new IFileStreambuf(filename))
{
}
IFileStream::~IFileStream()
{
- delete rdbuf();
+ delete rdbuf();
}
//---------------------------------------------------------------------------
OFileStream::OFileStream(const std::string& filename)
- : std::ostream(new OFileStreambuf(filename))
+ : std::ostream(new OFileStreambuf(filename))
{
}
OFileStream::~OFileStream()
{
- delete rdbuf();
+ delete rdbuf();
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __PHYSFSSTREAM_HPP__
-#define __PHYSFSSTREAM_HPP__
+#ifndef HEADER_SUPERTUX_PHYSFS_PHYSFS_STREAM_HPP
+#define HEADER_SUPERTUX_PHYSFS_PHYSFS_STREAM_HPP
-#include <stddef.h>
-#include <physfs.h>
-#include <string>
-#include <streambuf>
#include <iostream>
+#include <physfs.h>
/** This class implements a C++ streambuf object for physfs files.
* So that you can use normal istream operations on them
class IFileStreambuf : public std::streambuf
{
public:
- IFileStreambuf(const std::string& filename);
- ~IFileStreambuf();
+ IFileStreambuf(const std::string& filename);
+ ~IFileStreambuf();
protected:
- virtual int underflow();
- virtual pos_type seekoff(off_type pos, std::ios_base::seekdir,
- std::ios_base::openmode);
- virtual pos_type seekpos(pos_type pos, std::ios_base::openmode);
+ virtual int underflow();
+ virtual pos_type seekoff(off_type pos, std::ios_base::seekdir,
+ std::ios_base::openmode);
+ virtual pos_type seekpos(pos_type pos, std::ios_base::openmode);
private:
- PHYSFS_file* file;
- char buf[1024];
+ PHYSFS_file* file;
+ char buf[1024];
};
class OFileStreambuf : public std::streambuf
{
public:
- OFileStreambuf(const std::string& filename);
- ~OFileStreambuf();
+ OFileStreambuf(const std::string& filename);
+ ~OFileStreambuf();
protected:
- virtual int overflow(int c);
- virtual int sync();
+ virtual int overflow(int c);
+ virtual int sync();
private:
- PHYSFS_file* file;
- char buf[1024];
+ PHYSFS_file* file;
+ char buf[1024];
};
class IFileStream : public std::istream
{
public:
- IFileStream(const std::string& filename);
- ~IFileStream();
+ IFileStream(const std::string& filename);
+ ~IFileStream();
};
class OFileStream : public std::ostream
{
public:
- OFileStream(const std::string& filename);
- ~OFileStream();
+ OFileStream(const std::string& filename);
+ ~OFileStream();
};
#endif
+
+/* EOF */
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-#include <config.h>
-
-#include "physic.hpp"
-
-Physic::Physic()
- : ax(0), ay(0), vx(0), vy(0), gravity_enabled_flag(true), gravity(10 * 100)
-{
-}
-
-Physic::~Physic()
-{
-}
-
-void
-Physic::reset()
-{
- ax = ay = vx = vy = 0;
- gravity_enabled_flag = true;
-}
-
-void
-Physic::set_velocity_x(float nvx)
-{
- vx = nvx;
-}
-
-void
-Physic::set_velocity_y(float nvy)
-{
- vy = nvy;
-}
-
-void
-Physic::set_velocity(float nvx, float nvy)
-{
- vx = nvx;
- vy = nvy;
-}
-
-void
-Physic::set_velocity(const Vector& vector)
-{
- vx = vector.x;
- vy = vector.y;
-}
-
-void Physic::inverse_velocity_x()
-{
- vx = -vx;
-}
-
-void Physic::inverse_velocity_y()
-{
- vy = -vy;
-}
-
-float
-Physic::get_velocity_x() const
-{
- return vx;
-}
-
-float
-Physic::get_velocity_y() const
-{
- return vy;
-}
-
-Vector
-Physic::get_velocity() const
-{
- return Vector(vx, vy);
-}
-
-void
-Physic::set_acceleration_x(float nax)
-{
- ax = nax;
-}
-
-void
-Physic::set_acceleration_y(float nay)
-{
- ay = nay;
-}
-
-void
-Physic::set_acceleration(float nax, float nay)
-{
- ax = nax;
- ay = nay;
-}
-
-float
-Physic::get_acceleration_x() const
-{
- return ax;
-}
-
-float
-Physic::get_acceleration_y() const
-{
- return ay;
-}
-
-Vector
-Physic::get_acceleration() const
-{
- return Vector(ax, ay);
-}
-
-void
-Physic::enable_gravity(bool enable_gravity)
-{
- gravity_enabled_flag = enable_gravity;
-}
-
-bool
-Physic::gravity_enabled() const
-{
- return gravity_enabled_flag;
-}
-
-void
-Physic::set_gravity(float gravity)
-{
- this->gravity = gravity * 100;
-}
-
-float
-Physic::get_gravity() const
-{
- return gravity / 100;
-}
-
-Vector
-Physic::get_movement(float elapsed_time)
-{
- float grav = gravity_enabled_flag ? gravity : 0;
-
- vx += ax * elapsed_time;
- vy += (ay + grav) * elapsed_time;
- Vector result(vx * elapsed_time, vy * elapsed_time);
-
- return result;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-#ifndef SUPERTUX_PHYSIC_H
-#define SUPERTUX_PHYSIC_H
-
-#include "math/vector.hpp"
-
-/// Physics engine.
-/** This is a very simplistic physics engine handling accelerated and constant
- * movement along with gravity.
- */
-class Physic
-{
-public:
- Physic();
- ~Physic();
-
- /// Resets all velocities and accelerations to 0.
- void reset();
-
- /// Sets velocity to a fixed value.
- void set_velocity(float vx, float vy);
- void set_velocity(const Vector& vector);
-
- void set_velocity_x(float vx);
- void set_velocity_y(float vy);
-
- /// Velocity inversion.
- void inverse_velocity_x();
- void inverse_velocity_y();
-
- Vector get_velocity() const;
- float get_velocity_x() const;
- float get_velocity_y() const;
-
- /// Set acceleration.
- /** Sets acceleration applied to the object. (Note that gravity is
- * eventually added to the vertical acceleration)
- */
- void set_acceleration(float ax, float ay);
-
- void set_acceleration_x(float ax);
- void set_acceleration_y(float ay);
-
- Vector get_acceleration() const;
- float get_acceleration_x() const;
- float get_acceleration_y() const;
-
- /// Enables or disables handling of gravity.
- void enable_gravity(bool gravity_enabled);
- bool gravity_enabled() const;
-
- /// Set gravity to apply to object when enabled
- void set_gravity(float gravity);
-
- /// Get gravity to apply to object when enabled
- float get_gravity() const;
-
- Vector get_movement(float elapsed_time);
-
-private:
- /// horizontal and vertical acceleration
- float ax, ay;
- /// horizontal and vertical velocity
- float vx, vy;
- /// should we respect gravity in our calculations?
- bool gravity_enabled_flag;
- /// current gravity (multiplied by 100) to apply to object, if enabled
- float gravity;
-};
-
-class UsesPhysic
-{
-public:
- Physic physic;
- friend class Sector;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2003 Tobias Glaesser <tobi.web@gmx.de>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include <config.h>
-
-#include <math.h>
-#include "lisp/writer.hpp"
-#include "lisp/lisp.hpp"
-#include "player_status.hpp"
-#include "resources.hpp"
-#include "gettext.hpp"
-#include "video/drawing_context.hpp"
-#include "audio/sound_manager.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "math/vector.hpp"
-#include "main.hpp"
-#include "log.hpp"
-#include "timer.hpp"
-
-static const int START_COINS = 100;
-static const int MAX_COINS = 9999;
-
-PlayerStatus* player_status = 0;
-
-PlayerStatus::PlayerStatus()
- : coins(START_COINS),
- bonus(NO_BONUS),
- max_fire_bullets(0),
- max_ice_bullets(0)
-{
- reset();
-
- coin_surface.reset(new Surface("images/engine/hud/coins-0.png"));
- sound_manager->preload("sounds/coin.wav");
- sound_manager->preload("sounds/lifeup.wav");
-}
-
-PlayerStatus::~PlayerStatus()
-{
-}
-
-void PlayerStatus::reset()
-{
- coins = START_COINS;
- bonus = NO_BONUS;
-}
-
-void
-PlayerStatus::add_coins(int count, bool play_sound)
-{
- static float sound_played_time = 0;
- coins = std::min(coins + count, MAX_COINS);
- if(play_sound) {
- if(count >= 100)
- sound_manager->play("sounds/lifeup.wav");
- else if (real_time > sound_played_time + 0.010) {
- sound_manager->play("sounds/coin.wav");
- sound_played_time = real_time;
- }
- }
-}
-
-void
-PlayerStatus::write(lisp::Writer& writer)
-{
- switch(bonus) {
- case NO_BONUS:
- writer.write("bonus", "none");
- break;
- case GROWUP_BONUS:
- writer.write("bonus", "growup");
- break;
- case FIRE_BONUS:
- writer.write("bonus", "fireflower");
- break;
- case ICE_BONUS:
- writer.write("bonus", "iceflower");
- break;
- default:
- log_warning << "Unknown bonus type." << std::endl;
- writer.write("bonus", "none");
- }
- writer.write("fireflowers", max_fire_bullets);
- writer.write("iceflowers", max_ice_bullets);
-
- writer.write("coins", coins);
-}
-
-void
-PlayerStatus::read(const lisp::Lisp& lisp)
-{
- reset();
-
- std::string bonusname;
- if(lisp.get("bonus", bonusname)) {
- if(bonusname == "none") {
- bonus = NO_BONUS;
- } else if(bonusname == "growup") {
- bonus = GROWUP_BONUS;
- } else if(bonusname == "fireflower") {
- bonus = FIRE_BONUS;
- } else if(bonusname == "iceflower") {
- bonus = ICE_BONUS;
- } else {
- log_warning << "Unknown bonus '" << bonusname << "' in savefile" << std::endl;
- bonus = NO_BONUS;
- }
- }
- lisp.get("fireflowers", max_fire_bullets);
- lisp.get("iceflowers", max_ice_bullets);
-
- lisp.get("coins", coins);
-}
-
-void
-PlayerStatus::draw(DrawingContext& context)
-{
- static int displayed_coins = -1;
- static int next_count = 0;
-
- if ((displayed_coins == -1) || (fabsf(displayed_coins - coins) > 100)) {
- displayed_coins = coins;
- }
- if (++next_count > 2) {
- next_count = 0;
- if (displayed_coins < coins) displayed_coins++;
- if (displayed_coins > coins) displayed_coins--;
- }
- displayed_coins = std::min(std::max(displayed_coins, 0), 9999);
-
- std::stringstream ss;
- ss << displayed_coins;
- std::string coins_text = ss.str();
-
- context.push_transform();
- context.set_translation(Vector(0, 0));
-
- Surface* coin_surf = coin_surface.get();
- if (coin_surf) {
- context.draw_surface(coin_surf, Vector(SCREEN_WIDTH - BORDER_X - coin_surf->get_width() - fixed_font->get_text_width(coins_text), BORDER_Y + 1), LAYER_HUD);
- }
- context.draw_text(fixed_font, coins_text, Vector(SCREEN_WIDTH - BORDER_X, BORDER_Y), ALIGN_RIGHT, LAYER_HUD, PlayerStatus::text_color);
-
- context.pop_transform();
-}
-
-void
-PlayerStatus::operator= (const PlayerStatus& other)
-{
- coins = other.coins;
- bonus = other.bonus;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2003 Tobias Glaesser <tobi.web@gmx.de>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#ifndef SUPERTUX_PLAYERSTATUS_H
-#define SUPERTUX_PLAYERSTATUS_H
-
-#include <memory>
-#include "serializable.hpp"
-#include "video/color.hpp"
-
-namespace lisp{ class Writer; }
-namespace lisp{ class Lisp; }
-class Surface;
-
-static const float BORDER_X = 10;
-static const float BORDER_Y = 10;
-
-enum BonusType {
- NO_BONUS, GROWUP_BONUS, FIRE_BONUS, ICE_BONUS
-};
-class DrawingContext;
-
-/**
- * This class memorizes player status between different game sessions (for
- * example when switching maps in the worldmap)
- */
-class PlayerStatus : public Serializable
-{
- static Color text_color;
-public:
- PlayerStatus();
- ~PlayerStatus();
- void reset();
- void add_coins(int count, bool play_sound = true);
-
- void write(lisp::Writer& writer);
- void read(const lisp::Lisp& lisp);
-
- void draw(DrawingContext& context);
-
- int coins;
- BonusType bonus;
- int max_fire_bullets; /**< maximum number of fire bullets in play */
- int max_ice_bullets; /**< maximum number of ice bullets in play */
-
- void operator= (const PlayerStatus& other);
-
-private:
- // don't use this
- PlayerStatus(const PlayerStatus& other);
-
- std::auto_ptr<Surface> coin_surface;
-};
-
-// global player state
-extern PlayerStatus* player_status;
-
-#endif
+++ /dev/null
-// SuperTux
-// Copyright (C) 2008 Ingo Ruhnke <grumbel@gmx.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <sstream>
-#include "gameconfig.hpp"
-#include "gettext.hpp"
-#include "gui/menu.hpp"
-
-enum ProfileMenuIDs {
-
-};
-
-class ProfileMenu : public Menu
-{
-public:
- ProfileMenu() {
- add_label(_("Select Profile"));
- add_hl();
- for(int i = 0; i < 5; ++i)
- {
- std::ostringstream out;
- out << "Profile " << i+1;
- add_entry(i+1, out.str());
- }
-
- add_hl();
- add_back(_("Back"));
- }
-
- void menu_action(MenuItem* item) {
- config->profile = item->id;
- Menu::set_current(0);
- }
-};
-
-Menu* profile_menu = 0;
-
-Menu* get_profile_menu()
-{
- //static ProfileMenu menu;
- profile_menu = new ProfileMenu();
- return profile_menu;
-}
-
-void free_profile_menu()
-{
- delete profile_menu;
- profile_menu = 0;
-}
-
-/*
-std::string
-TitleScreen::get_slotinfo(int slot)
-{
- std::string tmp;
- std::string title;
-
- std::string basename = current_world->get_basedir();
- basename = basename.substr(0, basename.length()-1);
- std::string worlddirname = FileSystem::basename(basename);
- std::ostringstream stream;
- stream << "profile" << config->profile << "/" << worlddirname << "_" << slot << ".stsg";
- std::string slotfile = stream.str();
-
- try {
- lisp::Parser parser;
- const lisp::Lisp* root = parser.parse(slotfile);
-
- const lisp::Lisp* savegame = root->get_lisp("supertux-savegame");
- if(!savegame)
- throw std::runtime_error("file is not a supertux-savegame.");
-
- savegame->get("title", title);
- } catch(std::exception& ) {
- std::ostringstream slottitle;
- slottitle << _("Slot") << " " << slot << " - " << _("Free");
- return slottitle.str();
- }
-
- std::ostringstream slottitle;
- slottitle << _("Slot") << " " << slot << " - " << title;
- return slottitle.str();
-}
-*/
-
-/* EOF */
+++ /dev/null
-// SuperTux
-// Copyright (C) 2008 Ingo Ruhnke <grumbel@gmx.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#ifndef __PROFILE_MENU_HPP__
-#define __PROFILE_MENU_HPP__
-
-class Menu;
-Menu* get_profile_menu();
-void free_profile_menu();
-
-#endif
-
-/* EOF */
+++ /dev/null
-// $Id$
-//
-// A strong random number generator
-//
-// Copyright (C) 2006 Allen King
-// Copyright (C) 2002 Michael Ringgaard. All rights reserved.
-// Copyright (C) 1983, 1993 The Regents of the University of California.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions
-// are met:
-//
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-// 3. Neither the name of the project nor the names of its contributors
-// may be used to endorse or promote products derived from this software
-// without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-// SUCH DAMAGE.
-
-// Transliterated into C++ Allen King 060417, from sources on
-// http://www.jbox.dk/sanos/source/lib/random.c.html
-#include <config.h>
-
-
-#include <stdexcept>
-#include <stdio.h>
-#include <time.h>
-#include <cassert>
-#include "random_generator.hpp"
-
-RandomGenerator systemRandom; // global random number generator
-
-RandomGenerator::RandomGenerator() {
- assert(sizeof(int) >= 4);
- initialized = 0;
- debug = 0; // change this by hand for debug
- initialize();
-}
-
-RandomGenerator::~RandomGenerator() {
-}
-
-int RandomGenerator::srand(int x) {
- int x0 = x;
- while (x <= 0) // random seed of zero means
- x = time(0) % RandomGenerator::rand_max; // randomize with time
-
- if (debug > 0)
- printf("==== srand(%10d) (%10d) rand_max=%x =====\n",
- x, x0, RandomGenerator::rand_max);
-
- RandomGenerator::srandom(x);
- return x; // let caller know seed used
-}
-
-int RandomGenerator::rand() {
- int rv; // a positive int
- while ((rv = RandomGenerator::random()) <= 0) // neg or zero causes probs
- ;
- if (debug > 0)
- printf("==== rand(): %10d =====\n", rv);
- return rv;
-}
-
-int RandomGenerator::rand(int v) {
- assert(v >= 0 && v <= RandomGenerator::rand_max); // illegal arg
-
- // remove biases, esp. when v is large (e.g. v == (rand_max/4)*3;)
- int rv, maxV =(RandomGenerator::rand_max / v) * v;
- assert(maxV <= RandomGenerator::rand_max);
- while ((rv = RandomGenerator::random()) >= maxV)
- ;
- return rv % v; // mod it down to 0..(maxV-1)
-}
-
-int RandomGenerator::rand(int u, int v) {
- assert(v > u);
- return u + RandomGenerator::rand(v-u);
-}
-
-double RandomGenerator::randf(double v) {
- float rv;
- do {
- rv = ((double)RandomGenerator::random())/RandomGenerator::rand_max * v;
- } while (rv >= v); // rounding might cause rv==v
-
- if (debug > 0)
- printf("==== rand(): %f =====\n", rv);
- return rv;
-}
-
-double RandomGenerator::randf(double u, double v) {
- return u + RandomGenerator::randf(v-u);
-}
-
-//-----------------------------------------------------------------------
-//
-// Copyright (C) 2002 Michael Ringgaard. All rights reserved.
-// Copyright (C) 1983, 1993 The Regents of the University of California.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions
-// are met:
-//
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-// 3. Neither the name of the project nor the names of its contributors
-// may be used to endorse or promote products derived from this software
-// without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-// SUCH DAMAGE.
-//
-
-//**#include <os.h>
-
-//
-// An improved random number generation package. In addition to the standard
-// rand()/srand() like interface, this package also has a special state info
-// interface. The initstate() routine is called with a seed, an array of
-// bytes, and a count of how many bytes are being passed in; this array is
-// then initialized to contain information for random number generation with
-// that much state information. Good sizes for the amount of state
-// information are 32, 64, 128, and 256 bytes. The state can be switched by
-// calling the setstate() routine with the same array as was initialized
-// with initstate(). By default, the package runs with 128 bytes of state
-// information and generates far better random numbers than a linear
-// congruential generator. If the amount of state information is less than
-// 32 bytes, a simple linear congruential R.N.G. is used.
-//
-// Internally, the state information is treated as an array of longs; the
-// zeroeth element of the array is the type of R.N.G. being used (small
-// integer); the remainder of the array is the state information for the
-// R.N.G. Thus, 32 bytes of state information will give 7 longs worth of
-// state information, which will allow a degree seven polynomial. (Note:
-// the zeroeth word of state information also has some other information
-// stored in it -- see setstate() for details).
-//
-// The random number generation technique is a linear feedback shift register
-// approach, employing trinomials (since there are fewer terms to sum up that
-// way). In this approach, the least significant bit of all the numbers in
-// the state table will act as a linear feedback shift register, and will
-// have period 2^deg - 1 (where deg is the degree of the polynomial being
-// used, assuming that the polynomial is irreducible and primitive). The
-// higher order bits will have longer periods, since their values are also
-// influenced by pseudo-random carries out of the lower bits. The total
-// period of the generator is approximately deg*(2**deg - 1); thus doubling
-// the amount of state information has a vast influence on the period of the
-// generator. Note: the deg*(2**deg - 1) is an approximation only good for
-// large deg, when the period of the shift is the dominant factor.
-// With deg equal to seven, the period is actually much longer than the
-// 7*(2**7 - 1) predicted by this formula.
-//
-// Modified 28 December 1994 by Jacob S. Rosenberg.
-//
-
-//
-// For each of the currently supported random number generators, we have a
-// break value on the amount of state information (you need at least this
-// many bytes of state info to support this random number generator), a degree
-// for the polynomial (actually a trinomial) that the R.N.G. is based on, and
-// the separation between the two lower order coefficients of the trinomial.
-
-void RandomGenerator::initialize() {
-
-#define NSHUFF 100 // To drop part of seed -> 1st value correlation
-
-//static long degrees[MAX_TYPES] = { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 };
-//static long seps [MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 };
-
- degrees[0] = DEG_0;
- degrees[1] = DEG_1;
- degrees[2] = DEG_2;
- degrees[3] = DEG_3;
- degrees[4] = DEG_4;
-
- seps [0] = SEP_0;
- seps [1] = SEP_1;
- seps [2] = SEP_2;
- seps [3] = SEP_3;
- seps [4] = SEP_4;
-
-//
-// Initially, everything is set up as if from:
-//
-// initstate(1, randtbl, 128);
-//
-// Note that this initialization takes advantage of the fact that srandom()
-// advances the front and rear pointers 10*rand_deg times, and hence the
-// rear pointer which starts at 0 will also end up at zero; thus the zeroeth
-// element of the state information, which contains info about the current
-// position of the rear pointer is just
-//
-// MAX_TYPES * (rptr - state) + TYPE_3 == TYPE_3.
-
- randtbl[ 0] = TYPE_3;
- randtbl[ 1] = 0x991539b1;
- randtbl[ 2] = 0x16a5bce3;
- randtbl[ 3] = 0x6774a4cd;
- randtbl[ 4] = 0x3e01511e;
- randtbl[ 5] = 0x4e508aaa;
- randtbl[ 6] = 0x61048c05;
- randtbl[ 7] = 0xf5500617;
- randtbl[ 8] = 0x846b7115;
- randtbl[ 9] = 0x6a19892c;
- randtbl[10] = 0x896a97af;
- randtbl[11] = 0xdb48f936;
- randtbl[12] = 0x14898454;
- randtbl[13] = 0x37ffd106;
- randtbl[14] = 0xb58bff9c;
- randtbl[15] = 0x59e17104;
- randtbl[16] = 0xcf918a49;
- randtbl[17] = 0x09378c83;
- randtbl[18] = 0x52c7a471;
- randtbl[19] = 0x8d293ea9;
- randtbl[20] = 0x1f4fc301;
- randtbl[21] = 0xc3db71be;
- randtbl[22] = 0x39b44e1c;
- randtbl[23] = 0xf8a44ef9;
- randtbl[24] = 0x4c8b80b1;
- randtbl[25] = 0x19edc328;
- randtbl[26] = 0x87bf4bdd;
- randtbl[27] = 0xc9b240e5;
- randtbl[28] = 0xe9ee4b1b;
- randtbl[29] = 0x4382aee7;
- randtbl[30] = 0x535b6b41;
- randtbl[31] = 0xf3bec5da;
-
-// static long randtbl[DEG_3 + 1] =
-// {
-// TYPE_3;
-// 0x991539b1, 0x16a5bce3, 0x6774a4cd, 0x3e01511e, 0x4e508aaa, 0x61048c05,
-// 0xf5500617, 0x846b7115, 0x6a19892c, 0x896a97af, 0xdb48f936, 0x14898454,
-// 0x37ffd106, 0xb58bff9c, 0x59e17104, 0xcf918a49, 0x09378c83, 0x52c7a471,
-// 0x8d293ea9, 0x1f4fc301, 0xc3db71be, 0x39b44e1c, 0xf8a44ef9, 0x4c8b80b1,
-// 0x19edc328, 0x87bf4bdd, 0xc9b240e5, 0xe9ee4b1b, 0x4382aee7, 0x535b6b41,
-// 0xf3bec5da
-// };
-
-
-//
-// fptr and rptr are two pointers into the state info, a front and a rear
-// pointer. These two pointers are always rand_sep places aparts, as they
-// cycle cyclically through the state information. (Yes, this does mean we
-// could get away with just one pointer, but the code for random() is more
-// efficient this way). The pointers are left positioned as they would be
-// from the call
-//
-// initstate(1, randtbl, 128);
-//
-// (The position of the rear pointer, rptr, is really 0 (as explained above
-// in the initialization of randtbl) because the state table pointer is set
-// to point to randtbl[1] (as explained below).
-//
-
- fptr = &randtbl[SEP_3 + 1];
- rptr = &randtbl[1];
-
-//
-// The following things are the pointer to the state information table, the
-// type of the current generator, the degree of the current polynomial being
-// used, and the separation between the two pointers. Note that for efficiency
-// of random(), we remember the first location of the state information, not
-// the zeroeth. Hence it is valid to access state[-1], which is used to
-// store the type of the R.N.G. Also, we remember the last location, since
-// this is more efficient than indexing every time to find the address of
-// the last element to see if the front and rear pointers have wrapped.
-//
-
- state = &randtbl[1];
- rand_type = TYPE_3;
- rand_deg = DEG_3;
- rand_sep = SEP_3;
- end_ptr = &randtbl[DEG_3 + 1];
-
-}
-
-//
-// Compute x = (7^5 * x) mod (2^31 - 1)
-// without overflowing 31 bits:
-// (2^31 - 1) = 127773 * (7^5) + 2836
-// From "Random number generators: good ones are hard to find",
-// Park and Miller, Communications of the ACM, vol. 31, no. 10,
-// October 1988, p. 1195.
-//
-
-__inline static long good_rand(long x)
-{
- long hi, lo;
-
- // Can't be initialized with 0, so use another value.
- if (x == 0) x = 123459876;
- hi = x / 127773;
- lo = x % 127773;
- x = 16807 * lo - 2836 * hi;
- if (x < 0) x += 0x7fffffff;
- return x;
-}
-
-//
-// srandom
-//
-// Initialize the random number generator based on the given seed. If the
-// type is the trivial no-state-information type, just remember the seed.
-// Otherwise, initializes state[] based on the given "seed" via a linear
-// congruential generator. Then, the pointers are set to known locations
-// that are exactly rand_sep places apart. Lastly, it cycles the state
-// information a given number of times to get rid of any initial dependencies
-// introduced by the L.C.R.N.G. Note that the initialization of randtbl[]
-// for default usage relies on values produced by this routine.
-
-void RandomGenerator::srandom(unsigned long x)
-{
- long i, lim;
-
- state[0] = x;
- if (rand_type == TYPE_0)
- lim = NSHUFF;
- else
- {
- for (i = 1; i < rand_deg; i++) state[i] = good_rand(state[i - 1]);
- fptr = &state[rand_sep];
- rptr = &state[0];
- lim = 10 * rand_deg;
- }
-
- initialized = 1;
- for (i = 0; i < lim; i++) random();
-}
-
-#ifdef NOT_FOR_SUPERTUX // use in supertux doesn't require these methods,
- // which are not portable to as many platforms as
- // SDL. The cost is that the variability of the
- // initial seed is reduced to only 32 bits of
- // randomness, seemingly enough. PAK 060420
-//
-// srandomdev
-//
-// Many programs choose the seed value in a totally predictable manner.
-// This often causes problems. We seed the generator using the much more
-// secure random() interface. Note that this particular seeding
-// procedure can generate states which are impossible to reproduce by
-// calling srandom() with any value, since the succeeding terms in the
-// state buffer are no longer derived from the LC algorithm applied to
-// a fixed seed.
-
-void RandomGenerator::srandomdev()
-{
- int fd, done;
- size_t len;
-
- if (rand_type == TYPE_0)
- len = sizeof state[0];
- else
- len = rand_deg * sizeof state[0];
-
- done = 0;
- fd = open("/dev/urandom", O_RDONLY);
- if (fd >= 0)
- {
- if (read(fd, state, len) == len) done = 1;
- close(fd);
- }
-
- if (!done)
- {
- struct timeval tv;
-
- gettimeofday(&tv, NULL);
- srandom(tv.tv_sec ^ tv.tv_usec);
- return;
- }
-
- if (rand_type != TYPE_0)
- {
- fptr = &state[rand_sep];
- rptr = &state[0];
- }
- initialized = 1;
-}
-
-//
-// initstate
-//
-// Initialize the state information in the given array of n bytes for future
-// random number generation. Based on the number of bytes we are given, and
-// the break values for the different R.N.G.'s, we choose the best (largest)
-// one we can and set things up for it. srandom() is then called to
-// initialize the state information.
-//
-// Note that on return from srandom(), we set state[-1] to be the type
-// multiplexed with the current value of the rear pointer; this is so
-// successive calls to initstate() won't lose this information and will be
-// able to restart with setstate().
-//
-// Note: the first thing we do is save the current state, if any, just like
-// setstate() so that it doesn't matter when initstate is called.
-//
-// Returns a pointer to the old state.
-//
-
-char * RandomGenerator::initstate(unsigned long seed, char *arg_state, long n)
-{
- char *ostate = (char *) (&state[-1]);
- long *long_arg_state = (long *) arg_state;
-
- if (rand_type == TYPE_0)
- state[-1] = rand_type;
- else
- state[-1] = MAX_TYPES * (rptr - state) + rand_type;
-
- if (n < BREAK_0) return NULL;
-
- if (n < BREAK_1)
- {
- rand_type = TYPE_0;
- rand_deg = DEG_0;
- rand_sep = SEP_0;
- }
- else if (n < BREAK_2)
- {
- rand_type = TYPE_1;
- rand_deg = DEG_1;
- rand_sep = SEP_1;
- }
- else if (n < BREAK_3)
- {
- rand_type = TYPE_2;
- rand_deg = DEG_2;
- rand_sep = SEP_2;
- }
- else if (n < BREAK_4)
- {
- rand_type = TYPE_3;
- rand_deg = DEG_3;
- rand_sep = SEP_3;
- }
- else
- {
- rand_type = TYPE_4;
- rand_deg = DEG_4;
- rand_sep = SEP_4;
- }
-
- state = (long *) (long_arg_state + 1); // First location
- end_ptr = &state[rand_deg]; // Must set end_ptr before srandom
- srandom(seed);
-
- if (rand_type == TYPE_0)
- long_arg_state[0] = rand_type;
- else
- long_arg_state[0] = MAX_TYPES * (rptr - state) + rand_type;
-
- initialized = 1;
- return ostate;
-}
-
-//
-// setstate
-//
-// Restore the state from the given state array.
-//
-// Note: it is important that we also remember the locations of the pointers
-// in the current state information, and restore the locations of the pointers
-// from the old state information. This is done by multiplexing the pointer
-// location into the zeroeth word of the state information.
-//
-// Note that due to the order in which things are done, it is OK to call
-// setstate() with the same state as the current state.
-//
-// Returns a pointer to the old state information.
-//
-
-char * RandomGenerator::setstate(char *arg_state)
-{
- long *new_state = (long *) arg_state;
- long type = new_state[0] % MAX_TYPES;
- long rear = new_state[0] / MAX_TYPES;
- char *ostate = (char *) (&state[-1]);
-
- if (rand_type == TYPE_0)
- state[-1] = rand_type;
- else
- state[-1] = MAX_TYPES * (rptr - state) + rand_type;
-
- switch(type)
- {
- case TYPE_0:
- case TYPE_1:
- case TYPE_2:
- case TYPE_3:
- case TYPE_4:
- rand_type = type;
- rand_deg = degrees[type];
- rand_sep = seps[type];
- break;
- }
-
- state = (long *) (new_state + 1);
- if (rand_type != TYPE_0)
- {
- rptr = &state[rear];
- fptr = &state[(rear + rand_sep) % rand_deg];
- }
- end_ptr = &state[rand_deg]; // Set end_ptr too
-
- initialized = 1;
- return ostate;
-}
-#endif //NOT_FOR_SUPERTUX
-//
-// random:
-//
-// If we are using the trivial TYPE_0 R.N.G., just do the old linear
-// congruential bit. Otherwise, we do our fancy trinomial stuff, which is
-// the same in all the other cases due to all the global variables that have
-// been set up. The basic operation is to add the number at the rear pointer
-// into the one at the front pointer. Then both pointers are advanced to
-// the next location cyclically in the table. The value returned is the sum
-// generated, reduced to 31 bits by throwing away the "least random" low bit.
-//
-// Note: the code takes advantage of the fact that both the front and
-// rear pointers can't wrap on the same call by not testing the rear
-// pointer if the front one has wrapped.
-//
-// Returns a 31-bit random number.
-//
-
-long RandomGenerator::random()
-{
- long i;
- long *f, *r;
- if (!initialized) {
- throw std::runtime_error("uninitialized RandomGenerator object");
- }
-
- if (rand_type == TYPE_0)
- {
- i = state[0];
- state[0] = i = (good_rand(i)) & 0x7fffffff;
- }
- else
- {
- f = fptr; r = rptr;
- *f += *r;
- i = (*f >> 1) & 0x7fffffff; // Chucking least random bit
- if (++f >= end_ptr)
- {
- f = state;
- ++r;
- }
- else if (++r >= end_ptr)
- r = state;
-
- fptr = f; rptr = r;
- }
-
- return i;
-}
+++ /dev/null
-// $Id$
-//
-// A strong random number generator
-//
-// Copyright (C) 2006 Allen King
-// Copyright (C) 2002 Michael Ringgaard. All rights reserved.
-// Copyright (C) 1983, 1993 The Regents of the University of California.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions
-// are met:
-//
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-// 3. Neither the name of the project nor the names of its contributors
-// may be used to endorse or promote products derived from this software
-// without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-// SUCH DAMAGE.
-
-#ifndef __RANDOM_GENERATOR__
-#define __RANDOM_GENERATOR__
-
-class RandomGenerator
-{
-private:
-// Array versions of the above information to make code run faster --
-// relies on fact that TYPE_i == i.
- static const int TYPE_0 = 0; // Linear congruential
- static const int BREAK_0 = 8;
- static const int DEG_0 = 0;
- static const int SEP_0 = 0;
-
- static const int TYPE_1 = 1; // x**7 + x**3 + 1
- static const int BREAK_1 = 32;
- static const int DEG_1 = 7;
- static const int SEP_1 = 3;
-
- static const int TYPE_2 = 2; // x**15 + x + 1
- static const int BREAK_2 = 64;
- static const int DEG_2 = 15;
- static const int SEP_2 = 1;
-
- static const int TYPE_3 = 3; // x**31 + x**3 + 1
- static const int BREAK_3 = 128;
- static const int DEG_3 = 31;
- static const int SEP_3 = 3;
-
- static const int TYPE_4 = 4; // x**63 + x + 1
- static const int BREAK_4 = 256;
- static const int DEG_4 = 63;
- static const int SEP_4 = 1;
-
- static const int MAX_TYPES = 5; // Max number of types above
-
- bool initialized;
- long degrees[MAX_TYPES];
- long seps [MAX_TYPES];
- long randtbl[DEG_3 + 1];
-
- long *fptr;
- long *rptr;
-
- long *state;
- long rand_type;
- long rand_deg;
- long rand_sep;
- long *end_ptr;
- int debug;
- static const int rand_max = 0x7fffffff; // biggest signed Uint32
-
-public:
- RandomGenerator();
- ~RandomGenerator();
-
-// Documentation of user-visible calls:
-
- // Initialize the RNG with a 31-bit seed
- // if x is zero or absent, calls to time() will get a time-randomized seed
- // the value returned is the value of the seed used.
- int srand(int x=0);
-
- // generate random 31-bit numbers
- // calls to the following return a value evenly distributed between u (or
- // 0 if not specified) and v (or rand_max if not specified). Return
- // values may include u, but never v.
- int rand();
- int rand(int v);
- int rand(int u, int v);
- double randf(double v);
- double randf(double u, double v);
-
- // For Squirrel wrapper, since miniswig (and even squirrel?) doesn't
- // support function overloading or doubles
- int rand1i(int v) { return rand(v); }
- int rand2i(int u, int v) { return rand(u, v); }
- float rand1f(float v)
- { return static_cast<float>(randf(static_cast<double>(v))); }
- float rand2f(float u, float v)
- { return static_cast<float>(randf(static_cast<double>(u),
- static_cast<double>(v))); }
-
-//private:
- void initialize();
- void srandom(unsigned long x);
-// void srandomdev();
-// char *initstate(unsigned long seed, char *arg_state, long n);
-// char *setstate(char *arg_state);
- long random();
-};
-
-extern RandomGenerator systemRandom;
-
-#endif //__RANDOM_GENERATOR__
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-#ifndef __REF_HPP__
-#define __REF_HPP__
-
-/** This class behaves like a pointer to a refcounted object, but increments the
- * reference count when new objects are assigned and decrements the refcounter
- * when its lifetime has expired. (similar to std::auto_ptr)
- */
-template<typename T>
-class Ref
-{
-public:
- Ref(T* object = 0)
- : object(object)
- {
- if(object)
- object->ref();
- }
- Ref(const Ref<T>& other)
- : object(other.object)
- {
- if(object)
- object->ref();
- }
- ~Ref()
- {
- if(object)
- object->unref();
- }
-
- void operator= (const Ref<T>& other)
- {
- *this = other.get();
- }
-
- void operator= (T* object)
- {
- if(object)
- object->ref();
- if(this->object)
- this->object->unref();
- this->object = object;
- }
-
- T* operator ->() const
- {
- return object;
- }
-
- T& operator* () const
- {
- return *object;
- }
-
- operator const T* () const
- {
- return object;
- }
-
- T* get() const
- {
- return object;
- }
-
-private:
- T* object;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// Windstille - A Jump'n Shoot Game
-// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#ifndef __REFCOUNTER_HPP__
-#define __REFCOUNTER_HPP__
-
-#include <assert.h>
-
-/**
- * A base class that provides reference counting facilities
- */
-class RefCounter
-{
-public:
- RefCounter()
- : refcount(0)
- { }
-
- /** increases reference count */
- void ref()
- {
- refcount++;
- }
- /** decreases reference count. Destroys the object if the reference count
- * reaches 0
- */
- void unref()
- {
- refcount--;
- if(refcount <= 0) {
- delete this;
- }
- }
-
-protected:
- virtual ~RefCounter()
- {
- assert(refcount == 0);
- }
-
-private:
- int refcount;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2003 Tobias Glaesser <tobi.web@gmx.de>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include <config.h>
-
-#include "resources.hpp"
-
-#include "gui/mousecursor.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "tile_manager.hpp"
-#include "player_status.hpp"
-#include "video/font.hpp"
-
-MouseCursor* mouse_cursor = NULL;
-
-Font* fixed_font = NULL;
-Font* normal_font = NULL;
-Font* small_font = NULL;
-Font* big_font = NULL;
-
-/* Load graphics/sounds shared between all levels: */
-void load_shared()
-{
- /* Load the mouse-cursor */
- mouse_cursor = new MouseCursor("images/engine/menu/mousecursor.png");
- MouseCursor::set_current(mouse_cursor);
-
- /* Load global images: */
- fixed_font = new Font(Font::FIXED, "fonts/white.stf");
- normal_font = new Font(Font::VARIABLE, "fonts/white.stf");
- small_font = new Font(Font::VARIABLE, "fonts/white-small.stf", 1);
- big_font = new Font(Font::VARIABLE, "fonts/white-big.stf", 3);
-
- tile_manager = new TileManager();
- sprite_manager = new SpriteManager();
-
- player_status = new PlayerStatus();
-}
-
-/* Free shared data: */
-void unload_shared()
-{
- /* Free global images: */
- delete normal_font;
- delete small_font;
- delete big_font;
-
- delete sprite_manager;
- sprite_manager = NULL;
-
- /* Free mouse-cursor */
- delete mouse_cursor;
-
- delete player_status;
- player_status = NULL;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2003 Tobias Glaesser <tobi.web@gmx.de>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#ifndef SUPERTUX_RESOURCES_H
-#define SUPERTUX_RESOURCES_H
-
-class Font;
-class MouseCursor;
-
-extern MouseCursor* mouse_cursor;
-
-extern Font* fixed_font;
-extern Font* normal_font;
-extern Font* small_font;
-extern Font* big_font;
-
-void load_shared();
-void unload_shared();
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#ifndef __SCREEN_HPP__
-#define __SCREEN_HPP__
-
-class DrawingContext;
-
-/**
- * Abstract base class for code the MainLoop runs exclusively and full-screen.
- *
- * Examples of Screens are: The TitleScreen, a WorldMap, a level's
- * GameSession, a TextScroller, ...
- */
-class Screen
-{
-public:
- virtual ~Screen()
- {}
-
- /**
- * gets called before this screen gets activated (which is at least once
- * before the first draw or update call
- */
- virtual void setup()
- {}
- /** gets called when the current screen is temporarily suspended */
- virtual void leave()
- {}
-
- /**
- * gets called once per frame. The screen should draw itself in this function.
- * State changes should not be done in this function, but rather in update
- */
- virtual void draw(DrawingContext& context) = 0;
-
- /**
- * gets called for once (per logical) frame. Screens should do their state
- * updates and logic here
- */
- virtual void update(float elapsed_time) = 0;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#ifndef __SCREENFADE_HPP__
-#define __SCREENFADE_HPP__
-
-#include "screen.hpp"
-
-/**
- * Screen to be displayed simultaneously with another Screen.
- *
- * This is used for Screen transition effects like a fade-out or a shrink-fade
- */
-class ScreenFade : public Screen
-{
-public:
- virtual ~ScreenFade()
- {}
-
- /// returns true if the effect is completed
- virtual bool done() = 0;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-#ifndef __SCRIPT_INTERFACE_HPP__
-#define __SCRIPT_INTERFACE_HPP__
-
-#include <squirrel.h>
-
-/**
- * Objects that want to expose themself to the scripting environment
- * should implement this interface
- */
-class ScriptInterface
-{
-public:
- virtual ~ScriptInterface()
- {}
-
- virtual void expose(HSQUIRRELVM vm, SQInteger table_idx) = 0;
- virtual void unexpose(HSQUIRRELVM vm, SQInteger table_idx) = 0;
-};
-
-#endif
-#ifndef __SCRIPTING_AMBIENT_SOUND_H__
-#define __SCRIPTING_AMBIENT_SOUND_H__
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
-namespace Scripting
-{
+#ifndef HEADER_SUPERTUX_SCRIPTING_AMBIENT_SOUND_HPP
+#define HEADER_SUPERTUX_SCRIPTING_AMBIENT_SOUND_HPP
+
+namespace Scripting {
class AmbientSound
{
}
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __ANCHOR_POINTS_HPP__
-#define __ANCHOR_POINTS_HPP__
+#ifndef HEADER_SUPERTUX_SCRIPTING_ANCHOR_POINTS_HPP
+#define HEADER_SUPERTUX_SCRIPTING_ANCHOR_POINTS_HPP
namespace Scripting {
}
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <string>
-#include <stdio.h>
#include "object/camera.hpp"
+
#include "scripting/camera.hpp"
-#include "math/vector.hpp"
+#include "util/log.hpp"
#define NOIMPL log_fatal << __FUNCTION__ << " not implemented."
-namespace Scripting
-{
- Camera::Camera(::Camera* camera)
- : camera(camera)
- { }
+namespace Scripting {
+Camera::Camera(::Camera* camera)
+ : camera(camera)
+{ }
- Camera::~Camera()
- { }
+Camera::~Camera()
+{ }
- void
- Camera::reload_config()
- {
- camera->reload_config();
- }
+void
+Camera::reload_config()
+{
+ camera->reload_config();
+}
- void
- Camera::shake(float speed, float x, float y)
- {
- camera->shake(speed, x, y);
- }
+void
+Camera::shake(float speed, float x, float y)
+{
+ camera->shake(speed, x, y);
+}
- void
- Camera::set_pos(float , float )
- {
- }
+void
+Camera::set_pos(float , float )
+{
+}
- void
- Camera::set_mode(const std::string& mode)
- {
- if(mode == "normal") {
- camera->mode = ::Camera::NORMAL;
- } else if(mode == "manual") {
- camera->mode = ::Camera::MANUAL;
- } else {
- log_fatal << "Camera mode '" << mode << "' unknown.";
- }
+void
+Camera::set_mode(const std::string& mode)
+{
+ if(mode == "normal") {
+ camera->mode = ::Camera::NORMAL;
+ } else if(mode == "manual") {
+ camera->mode = ::Camera::MANUAL;
+ } else {
+ log_fatal << "Camera mode '" << mode << "' unknown.";
}
+}
- void
- Camera::scroll_to(float x, float y, float scrolltime)
- {
- camera->scroll_to(Vector(x, y), scrolltime);
- }
+void
+Camera::scroll_to(float x, float y, float scrolltime)
+{
+ camera->scroll_to(Vector(x, y), scrolltime);
}
+}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __CAMERA_H__
-#define __CAMERA_H__
+#ifndef HEADER_SUPERTUX_SCRIPTING_CAMERA_HPP
+#define HEADER_SUPERTUX_SCRIPTING_CAMERA_HPP
#ifndef SCRIPTING_API
class Camera;
typedef Camera _Camera;
-#include <string>
#endif
-namespace Scripting
-{
+namespace Scripting {
class Camera
{
}
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <string>
-#include <stdio.h>
#include "object/candle.hpp"
#include "scripting/candle.hpp"
-#include "math/vector.hpp"
#define NOIMPL log_fatal << __PRETTY_FUNCTION__ << " not implemented."
-namespace Scripting
-{
+namespace Scripting {
- Candle::Candle(::Candle* candle)
- : candle(candle)
- { }
+Candle::Candle(::Candle* candle)
+ : candle(candle)
+{ }
- Candle::~Candle()
- { }
+Candle::~Candle()
+{ }
- bool Candle::get_burning()
- {
- return candle->get_burning();
- }
+bool Candle::get_burning()
+{
+ return candle->get_burning();
+}
- void Candle::set_burning(bool burning)
- {
- candle->set_burning(burning);
- }
+void Candle::set_burning(bool burning)
+{
+ candle->set_burning(burning);
+}
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __SCRIPTING_CANDLE_H__
-#define __SCRIPTING_CANDLE_H__
+#ifndef HEADER_SUPERTUX_SCRIPTING_CANDLE_HPP
+#define HEADER_SUPERTUX_SCRIPTING_CANDLE_HPP
#ifndef SCRIPTING_API
class Candle;
typedef Candle _Candle;
#endif
-namespace Scripting
-{
+namespace Scripting {
class Candle
{
#ifndef SCRIPTING_API
_Candle* candle;
+
+private:
+ Candle(const Candle&);
+ Candle& operator=(const Candle&);
#endif
};
}
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __SCRIPTING_DISPLAY_EFFECT_H__
-#define __SCRIPTING_DISPLAY_EFFECT_H__
+#ifndef HEADER_SUPERTUX_SCRIPTING_DISPLAY_EFFECT_HPP
+#define HEADER_SUPERTUX_SCRIPTING_DISPLAY_EFFECT_HPP
-namespace Scripting
-{
+namespace Scripting {
class DisplayEffect
{
public:
#ifndef SCRIPTING_API
- virtual ~DisplayEffect()
- {}
+ virtual ~DisplayEffect()
+ {}
#endif
- /// fade display to black
- virtual void fade_out(float fadetime) = 0;
- /// fade display from black to normal
- virtual void fade_in(float fadetime) = 0;
- /// set display black (or back to normal)
- virtual void set_black(bool enabled) = 0;
- /// check if display is set to black
- virtual bool is_black() = 0;
- /// set black borders for cutscenes
- virtual void sixteen_to_nine(float fadetime) = 0;
- /// deactivate borders
- virtual void four_to_three(float fadetime) = 0;
-
- // fade display until just a small visible circle is left
- // (like what happens in some cartoons at the end)
- // void shrink_fade(Vector goal, float radius, float fadetime);
+ /// fade display to black
+ virtual void fade_out(float fadetime) = 0;
+ /// fade display from black to normal
+ virtual void fade_in(float fadetime) = 0;
+ /// set display black (or back to normal)
+ virtual void set_black(bool enabled) = 0;
+ /// check if display is set to black
+ virtual bool is_black() = 0;
+ /// set black borders for cutscenes
+ virtual void sixteen_to_nine(float fadetime) = 0;
+ /// deactivate borders
+ virtual void four_to_three(float fadetime) = 0;
+
+ // fade display until just a small visible circle is left
+ // (like what happens in some cartoons at the end)
+ // void shrink_fade(Vector goal, float radius, float fadetime);
};
}
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <assert.h>
#include <stdexcept>
-#include "floating_image.hpp"
-#include "sector.hpp"
+
#include "object/floating_image.hpp"
+#include "scripting/floating_image.hpp"
+#include "supertux/sector.hpp"
#include "worldmap/worldmap.hpp"
-namespace Scripting
-{
+namespace Scripting {
FloatingImage::FloatingImage(const std::string& spritefile)
{
floating_image->fade_out(fadetime);
}
-
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __FLOATING_IMAGE_HPP__
-#define __FLOATING_IMAGE_HPP__
+#ifndef HEADER_SUPERTUX_SCRIPTING_FLOATING_IMAGE_HPP
+#define HEADER_SUPERTUX_SCRIPTING_FLOATING_IMAGE_HPP
#ifndef SCRIPTING_API
-#define __suspend
-#include <string>
-#include "ref.hpp"
+#define HEADER_SUPERTUX_SCRIPTING_FLOATING_IMAGE_HPP
+
+#include "util/ref.hpp"
class FloatingImage;
typedef FloatingImage _FloatingImage;
#endif
-namespace Scripting
-{
+namespace Scripting {
class FloatingImage
{
}
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
-
-#include <memory>
-#include <stdio.h>
-#include <string>
-#include <squirrel.h>
-#include <sqstdio.h>
-#include "textscroller.hpp"
-#include "functions.hpp"
-#include "game_session.hpp"
-#include "tinygettext/tinygettext.hpp"
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#include "scripting/functions.hpp"
+
+#include "audio/sound_manager.hpp"
+#include "math/random_generator.hpp"
+#include "object/camera.hpp"
+#include "object/player.hpp"
#include "physfs/physfs_stream.hpp"
-#include "resources.hpp"
-#include "gettext.hpp"
-#include "log.hpp"
-#include "mainloop.hpp"
-#include "worldmap/worldmap.hpp"
+#include "supertux/fadeout.hpp"
+#include "supertux/game_session.hpp"
+#include "supertux/gameconfig.hpp"
+#include "supertux/main.hpp"
+#include "supertux/mainloop.hpp"
+#include "supertux/sector.hpp"
+#include "supertux/shrinkfade.hpp"
+#include "supertux/textscroller.hpp"
+#include "supertux/world.hpp"
+#include "util/gettext.hpp"
#include "worldmap/tux.hpp"
-#include "world.hpp"
-#include "sector.hpp"
-#include "gameconfig.hpp"
-#include "object/player.hpp"
-#include "object/tilemap.hpp"
-#include "main.hpp"
-#include "fadeout.hpp"
-#include "shrinkfade.hpp"
-#include "object/camera.hpp"
-#include "flip_level_transformer.hpp"
-#include "audio/sound_manager.hpp"
-#include "random_generator.hpp"
-#include "squirrel_error.hpp"
-#include "squirrel_util.hpp"
-#include "time_scheduler.hpp"
+#include "scripting/squirrel_util.hpp"
+#include "scripting/time_scheduler.hpp"
-extern float game_speed;
+extern float g_game_speed;
-namespace Scripting
-{
+namespace Scripting {
SQInteger display(HSQUIRRELVM vm)
{
void wait_for_screenswitch(HSQUIRRELVM vm)
{
- main_loop->waiting_threads.add(vm);
+ g_main_loop->waiting_threads.add(vm);
}
void exit_screen()
{
- main_loop->exit_screen();
+ g_main_loop->exit_screen();
}
void fadeout_screen(float seconds)
{
- main_loop->set_screen_fade(new FadeOut(seconds));
+ g_main_loop->set_screen_fade(new FadeOut(seconds));
}
void shrink_screen(float dest_x, float dest_y, float seconds)
{
- main_loop->set_screen_fade(new ShrinkFade(Vector(dest_x, dest_y), seconds));
+ g_main_loop->set_screen_fade(new ShrinkFade(Vector(dest_x, dest_y), seconds));
}
void abort_screenfade()
{
- main_loop->set_screen_fade(NULL);
+ g_main_loop->set_screen_fade(NULL);
}
std::string translate(const std::string& text)
void display_text_file(const std::string& filename)
{
- main_loop->push_screen(new TextScroller(filename));
+ g_main_loop->push_screen(new TextScroller(filename));
}
void load_worldmap(const std::string& filename)
{
using namespace WorldMapNS;
- main_loop->push_screen(new WorldMap(filename));
+ g_main_loop->push_screen(new WorldMap(filename));
}
void load_level(const std::string& filename)
{
- main_loop->push_screen(new GameSession(filename));
+ g_main_loop->push_screen(new GameSession(filename));
}
static SQInteger squirrel_read_char(SQUserPointer file)
IFileStream in(filename);
if(SQ_FAILED(sq_compile(vm, squirrel_read_char, &in,
- filename.c_str(), SQTrue)))
+ filename.c_str(), SQTrue)))
throw SquirrelError(vm, "Couldn't parse script");
sq_pushroottable(vm);
void debug_show_fps(bool enable)
{
- config->show_fps = enable;
+ g_config->show_fps = enable;
}
void debug_draw_solids_only(bool enable)
{
if (!validate_sector_player()) return;
::Player* tux = Sector::current()->player; // Scripting::Player != ::Player
- tux->physic.set_velocity_x(tux->physic.get_velocity_x()*3);
+ tux->get_physic().set_velocity_x(tux->get_physic().get_velocity_x()*3);
}
void invincible()
if (!validate_sector_player()) return;
::Player* tux = Sector::current()->player;
tux->move(Vector(
- (Sector::current()->get_width()) - (SCREEN_WIDTH*2), 0));
+ (Sector::current()->get_width()) - (SCREEN_WIDTH*2), 0));
Sector::current()->camera->reset(
- Vector(tux->get_pos().x, tux->get_pos().y));
+ Vector(tux->get_pos().x, tux->get_pos().y));
}
void camera()
void quit()
{
- main_loop->quit();
+ g_main_loop->quit();
}
int rand()
void set_game_speed(float speed)
{
- ::game_speed = speed;
+ ::g_game_speed = speed;
}
void record_demo(const std::string& filename)
return;
}
// Reset random seed
- config->random_seed = GameSession::current()->get_demo_random_seed(filename);
- config->random_seed = systemRandom.srand(config->random_seed);
+ g_config->random_seed = GameSession::current()->get_demo_random_seed(filename);
+ g_config->random_seed = systemRandom.srand(g_config->random_seed);
GameSession::current()->restart_level();
GameSession::current()->play_demo(filename);
}
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __FUNCTIONS_H__
-#define __FUNCTIONS_H__
+#ifndef HEADER_SUPERTUX_SCRIPTING_FUNCTIONS_HPP
+#define HEADER_SUPERTUX_SCRIPTING_FUNCTIONS_HPP
#ifndef SCRIPTING_API
+#include <squirrel.h>
+#include <string>
+
#define __suspend
#define __custom(x)
-#include <string>
#endif
-namespace Scripting
-{
+namespace Scripting {
/**
* Display the value of the argument. This is useful for inspecting tables.
*/
void play_demo(const std::string& filename);
-}
+} // namespace Scripting
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <string>
-#include <stdio.h>
-#include "level.hpp"
-#include "game_session.hpp"
-#include "flip_level_transformer.hpp"
+#include "supertux/flip_level_transformer.hpp"
+#include "supertux/game_session.hpp"
-namespace Scripting
+namespace Scripting {
+void
+Level_finish(bool win)
{
- void
- Level_finish(bool win)
- {
- if(GameSession::current() == NULL)
- return;
+ if(GameSession::current() == NULL)
+ return;
- GameSession::current()->finish(win);
- }
+ GameSession::current()->finish(win);
+}
- void
- Level_spawn(const std::string& sector, const std::string& spawnpoint)
- {
- if(GameSession::current() == NULL)
- return;
+void
+Level_spawn(const std::string& sector, const std::string& spawnpoint)
+{
+ if(GameSession::current() == NULL)
+ return;
- GameSession::current()->respawn(sector, spawnpoint);
- }
+ GameSession::current()->respawn(sector, spawnpoint);
+}
- void
- Level_flip_vertically()
- {
- FlipLevelTransformer flip_transformer;
- flip_transformer.transform(GameSession::current()->get_current_level());
- }
+void
+Level_flip_vertically()
+{
+ FlipLevelTransformer flip_transformer;
+ flip_transformer.transform(GameSession::current()->get_current_level());
+}
- void
- Level_toggle_pause()
- {
- if(GameSession::current() == NULL)
- return;
- GameSession::current()->toggle_pause();
- }
+void
+Level_toggle_pause()
+{
+ if(GameSession::current() == NULL)
+ return;
+ GameSession::current()->toggle_pause();
+}
- void
- Level_edit(bool edit_mode)
- {
- if(GameSession::current() == NULL) return;
- GameSession::current()->set_editmode(edit_mode);
- }
+void
+Level_edit(bool edit_mode)
+{
+ if(GameSession::current() == NULL) return;
+ GameSession::current()->set_editmode(edit_mode);
+}
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __LEVEL_H__
-#define __LEVEL_H__
+#ifndef HEADER_SUPERTUX_SCRIPTING_LEVEL_HPP
+#define HEADER_SUPERTUX_SCRIPTING_LEVEL_HPP
-namespace Scripting
-{
+namespace Scripting {
- /** Instantly finish the currently played level */
- void Level_finish(bool win);
- /** spawn tux at specified sector and spawnpoint */
- void Level_spawn(const std::string& sector, const std::string& spawnpoint);
- /** Flip level vertically */
- void Level_flip_vertically();
- /** toggle pause */
- void Level_toggle_pause();
+/** Instantly finish the currently played level */
+void Level_finish(bool win);
+/** spawn tux at specified sector and spawnpoint */
+void Level_spawn(const std::string& sector, const std::string& spawnpoint);
+/** Flip level vertically */
+void Level_flip_vertically();
+/** toggle pause */
+void Level_toggle_pause();
- /** Switch to and from edit mode */
- void Level_edit(bool edit_mode);
+/** Switch to and from edit mode */
+void Level_edit(bool edit_mode);
}
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <string>
-#include <stdio.h>
#include "object/level_time.hpp"
#include "scripting/level_time.hpp"
-#include "math/vector.hpp"
#define NOIMPL log_fatal << __PRETTY_FUNCTION__ << " not implemented."
-namespace Scripting
-{
+namespace Scripting {
- LevelTime::LevelTime(::LevelTime* level_time)
- : level_time(level_time)
- { }
+LevelTime::LevelTime(::LevelTime* level_time)
+ : level_time(level_time)
+{ }
- LevelTime::~LevelTime()
- { }
+LevelTime::~LevelTime()
+{ }
- void LevelTime::start()
- {
- level_time->start();
- }
+void LevelTime::start()
+{
+ level_time->start();
+}
- void LevelTime::stop()
- {
- level_time->stop();
- }
+void LevelTime::stop()
+{
+ level_time->stop();
+}
- float LevelTime::get_time()
- {
- return level_time->get_time();
- }
+float LevelTime::get_time()
+{
+ return level_time->get_time();
+}
- void LevelTime::set_time(float time_left)
- {
- level_time->set_time(time_left);
- }
+void LevelTime::set_time(float time_left)
+{
+ level_time->set_time(time_left);
+}
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __SCRIPTING_LEVELTIME_H__
-#define __SCRIPTING_LEVELTIME_H__
+#ifndef HEADER_SUPERTUX_SCRIPTING_LEVEL_TIME_HPP
+#define HEADER_SUPERTUX_SCRIPTING_LEVEL_TIME_HPP
#ifndef SCRIPTING_API
class LevelTime;
typedef LevelTime _LevelTime;
#endif
-namespace Scripting
-{
+namespace Scripting {
class LevelTime
{
}
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <string>
-#include <stdio.h>
#include "object/platform.hpp"
#include "scripting/platform.hpp"
-#include "math/vector.hpp"
#define NOIMPL log_fatal << __PRETTY_FUNCTION__ << " not implemented."
-namespace Scripting
-{
+namespace Scripting {
- Platform::Platform(::Platform* platform)
- : platform(platform)
- { }
+Platform::Platform(::Platform* platform)
+ : platform(platform)
+{ }
- Platform::~Platform()
- { }
+Platform::~Platform()
+{ }
- void Platform::goto_node(int node_no)
- {
- platform->goto_node(node_no);
- }
+void Platform::goto_node(int node_no)
+{
+ platform->goto_node(node_no);
+}
- void Platform::start_moving()
- {
- platform->start_moving();
- }
+void Platform::start_moving()
+{
+ platform->start_moving();
+}
- void Platform::stop_moving()
- {
- platform->stop_moving();
- }
+void Platform::stop_moving()
+{
+ platform->stop_moving();
+}
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __SCRIPTING_PLATFORM_H__
-#define __SCRIPTING_PLATFORM_H__
+#ifndef HEADER_SUPERTUX_SCRIPTING_PLATFORM_HPP
+#define HEADER_SUPERTUX_SCRIPTING_PLATFORM_HPP
#ifndef SCRIPTING_API
class Platform;
typedef Platform _Platform;
#endif
-namespace Scripting
-{
+namespace Scripting {
class Platform
{
}
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __SCRIPTING_PLAYER_H__
-#define __SCRIPTING_PLAYER_H__
+#ifndef HEADER_SUPERTUX_SCRIPTING_PLAYER_HPP
+#define HEADER_SUPERTUX_SCRIPTING_PLAYER_HPP
-namespace Scripting
-{
+#ifndef SCRIPTING_API
+#include <string>
+#endif
+
+namespace Scripting {
class Player
{
}
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __SCRIPTED_OBJECT_INTERFACE_H__
-#define __SCRIPTED_OBJECT_INTERFACE_H__
+#ifndef HEADER_SUPERTUX_SCRIPTING_SCRIPTED_OBJECT_HPP
+#define HEADER_SUPERTUX_SCRIPTING_SCRIPTED_OBJECT_HPP
-namespace Scripting
-{
+namespace Scripting {
class ScriptedObject
{
}
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "serialize.hpp"
+#include "scripting/serialize.hpp"
+
+#include <iostream>
-#include <memory>
-#include <assert.h>
-#include "lisp/lisp.hpp"
-#include "lisp/list_iterator.hpp"
-#include "lisp/parser.hpp"
#include "lisp/writer.hpp"
-#include "squirrel_error.hpp"
+#include "lisp/list_iterator.hpp"
+#include "scripting/squirrel_error.hpp"
-namespace Scripting
-{
+namespace Scripting {
void load_squirrel_table(HSQUIRRELVM vm, SQInteger table_idx, const lisp::Lisp* lisp)
{
sq_pop(vm, 1);
}
-}
+} // namespace Scripting
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __SERIALIZE_HPP__
-#define __SERIALIZE_HPP__
+#ifndef HEADER_SUPERTUX_SCRIPTING_SERIALIZE_HPP
+#define HEADER_SUPERTUX_SCRIPTING_SERIALIZE_HPP
#include <squirrel.h>
-#include <string>
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-namespace Scripting
-{
+namespace lisp {
+class Lisp;
+class Writer;
+} // namespace lisp
+
+namespace Scripting {
- void save_squirrel_table(HSQUIRRELVM vm, SQInteger table_idx, lisp::Writer& writer);
- void load_squirrel_table(HSQUIRRELVM vm, SQInteger table_idx, const lisp::Lisp* lisp);
+void save_squirrel_table(HSQUIRRELVM vm, SQInteger table_idx, lisp::Writer& writer);
+void load_squirrel_table(HSQUIRRELVM vm, SQInteger table_idx, const lisp::Lisp* lisp);
-}
+} // namespace Scripting
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "squirrel_error.hpp"
+#include "scripting/squirrel_error.hpp"
#include <sstream>
-namespace Scripting
-{
+namespace Scripting {
SquirrelError::SquirrelError(HSQUIRRELVM v, const std::string& message) throw()
{
}
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __SQUIRREL_ERROR_HPP__
-#define __SQUIRREL_ERROR_HPP__
+#ifndef HEADER_SUPERTUX_SCRIPTING_SQUIRREL_ERROR_HPP
+#define HEADER_SUPERTUX_SCRIPTING_SQUIRREL_ERROR_HPP
#include <squirrel.h>
#include <stdexcept>
-namespace Scripting
-{
+namespace Scripting {
/** Exception class for squirrel errors, it takes a squirrelvm and uses
* sq_geterror() to retrieve additional information about the last error that
}
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#include "scripting/squirrel_util.hpp"
+
#include <config.h>
-#include <stdexcept>
-#include <sstream>
-#include <stdarg.h>
-#include <squirrel.h>
-#include <sqstdmath.h>
+#include <stdio.h>
+#include <sqstdaux.h>
#include <sqstdblob.h>
+#include <sqstdmath.h>
#include <sqstdstring.h>
-#include <sqstdaux.h>
-#include <sqstdio.h>
-#include "squirrel_util.hpp"
-#include "log.hpp"
-#include "level.hpp"
+#include <stdarg.h>
+
#include "physfs/physfs_stream.hpp"
-#include "random_generator.hpp"
+#include "supertux/console.hpp"
+#include "util/log.hpp"
#ifdef ENABLE_SQDBG
-#include <sqdbg/sqrdbg.h>
static HSQREMOTEDBG debugger = NULL;
#endif
-namespace Scripting
-{
+namespace Scripting {
HSQUIRRELVM global_vm = NULL;
{
std::ostringstream os;
switch(sq_gettype(v, i))
- {
+ {
case OT_NULL:
os << "<null>";
break;
os << "{";
sq_pushnull(v); //null iterator
while(SQ_SUCCEEDED(sq_next(v,i-1)))
- {
- if (!first) {
- os << ", ";
- }
- first = false;
+ {
+ if (!first) {
+ os << ", ";
+ }
+ first = false;
- //here -1 is the value and -2 is the key
- os << squirrel2string(v, -2) << " => "
- << squirrel2string(v, -1);
+ //here -1 is the value and -2 is the key
+ os << squirrel2string(v, -2) << " => "
+ << squirrel2string(v, -1);
- sq_pop(v,2); //pops key and val before the nex iteration
- }
+ sq_pop(v,2); //pops key and val before the nex iteration
+ }
sq_pop(v, 1);
os << "}";
break;
os << "[";
sq_pushnull(v); //null iterator
while(SQ_SUCCEEDED(sq_next(v,i-1)))
- {
- if (!first) {
- os << ", ";
- }
- first = false;
+ {
+ if (!first) {
+ os << ", ";
+ }
+ first = false;
- //here -1 is the value and -2 is the key
- // we ignore the key, since that is just the index in an array
- os << squirrel2string(v, -1);
+ //here -1 is the value and -2 is the key
+ // we ignore the key, since that is just the index in an array
+ os << squirrel2string(v, -1);
- sq_pop(v,2); //pops key and val before the nex iteration
- }
+ sq_pop(v,2); //pops key and val before the nex iteration
+ }
sq_pop(v, 1);
os << "]";
break;
default:
os << "<unknown>";
break;
- }
+ }
return os.str();
}
void print_squirrel_stack(HSQUIRRELVM v)
{
- printf("--------------------------------------------------------------\n");
- int count = sq_gettop(v);
- for(int i = 1; i <= count; ++i) {
- printf("%d: ",i);
- switch(sq_gettype(v, i))
- {
- case OT_NULL:
- printf("null");
- break;
- case OT_INTEGER: {
- SQInteger val;
- sq_getinteger(v, i, &val);
- printf("integer (%d)", static_cast<int> (val));
- break;
- }
- case OT_FLOAT: {
- SQFloat val;
- sq_getfloat(v, i, &val);
- printf("float (%f)", val);
- break;
- }
- case OT_STRING: {
- const SQChar* val;
- sq_getstring(v, i, &val);
- printf("string (%s)", val);
- break;
- }
- case OT_TABLE:
- printf("table");
- break;
- case OT_ARRAY:
- printf("array");
- break;
- case OT_USERDATA:
- printf("userdata");
- break;
- case OT_CLOSURE:
- printf("closure(function)");
- break;
- case OT_NATIVECLOSURE:
- printf("native closure(C function)");
- break;
- case OT_GENERATOR:
- printf("generator");
- break;
- case OT_USERPOINTER:
- printf("userpointer");
- break;
- case OT_THREAD:
- printf("thread");
- break;
- case OT_CLASS:
- printf("class");
- break;
- case OT_INSTANCE:
- printf("instance");
- break;
- case OT_WEAKREF:
- printf("weakref");
- break;
- default:
- printf("unknown?!?");
- break;
- }
- printf("\n");
+ printf("--------------------------------------------------------------\n");
+ int count = sq_gettop(v);
+ for(int i = 1; i <= count; ++i) {
+ printf("%d: ",i);
+ switch(sq_gettype(v, i))
+ {
+ case OT_NULL:
+ printf("null");
+ break;
+ case OT_INTEGER: {
+ SQInteger val;
+ sq_getinteger(v, i, &val);
+ printf("integer (%d)", static_cast<int> (val));
+ break;
+ }
+ case OT_FLOAT: {
+ SQFloat val;
+ sq_getfloat(v, i, &val);
+ printf("float (%f)", val);
+ break;
+ }
+ case OT_STRING: {
+ const SQChar* val;
+ sq_getstring(v, i, &val);
+ printf("string (%s)", val);
+ break;
+ }
+ case OT_TABLE:
+ printf("table");
+ break;
+ case OT_ARRAY:
+ printf("array");
+ break;
+ case OT_USERDATA:
+ printf("userdata");
+ break;
+ case OT_CLOSURE:
+ printf("closure(function)");
+ break;
+ case OT_NATIVECLOSURE:
+ printf("native closure(C function)");
+ break;
+ case OT_GENERATOR:
+ printf("generator");
+ break;
+ case OT_USERPOINTER:
+ printf("userpointer");
+ break;
+ case OT_THREAD:
+ printf("thread");
+ break;
+ case OT_CLASS:
+ printf("class");
+ break;
+ case OT_INSTANCE:
+ printf("instance");
+ break;
+ case OT_WEAKREF:
+ printf("weakref");
+ break;
+ default:
+ printf("unknown?!?");
+ break;
}
- printf("--------------------------------------------------------------\n");
+ printf("\n");
+ }
+ printf("--------------------------------------------------------------\n");
}
static SQInteger squirrel_read_char(SQUserPointer file)
return result;
}
-
std::string read_string(HSQUIRRELVM vm, const char* name)
{
sq_pushstring(vm, name, -1);
// end: serialization functions
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#ifndef __SQUIRREL_UTIL_HPP__
-#define __SQUIRREL_UTIL_HPP__
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_SCRIPTING_SQUIRREL_UTIL_HPP
+#define HEADER_SUPERTUX_SCRIPTING_SQUIRREL_UTIL_HPP
-#include <squirrel.h>
#include <sstream>
-#include <stdexcept>
-#include <string>
-#include "wrapper.hpp"
-#include "squirrel_error.hpp"
-namespace Scripting
-{
+#include "scripting/squirrel_error.hpp"
+#include "scripting/wrapper.hpp"
- extern HSQUIRRELVM global_vm;
+namespace Scripting {
- void init_squirrel(bool enable_debugger);
- void exit_squirrel();
- void update_debugger();
+extern HSQUIRRELVM global_vm;
- std::string squirrel2string(HSQUIRRELVM vm, SQInteger i);
- void print_squirrel_stack(HSQUIRRELVM vm);
+void init_squirrel(bool enable_debugger);
+void exit_squirrel();
+void update_debugger();
- HSQOBJECT create_thread(HSQUIRRELVM vm);
- SQObject vm_to_object(HSQUIRRELVM vm);
- HSQUIRRELVM object_to_vm(HSQOBJECT object);
+std::string squirrel2string(HSQUIRRELVM vm, SQInteger i);
+void print_squirrel_stack(HSQUIRRELVM vm);
- void compile_script(HSQUIRRELVM vm, std::istream& in,
- const std::string& sourcename);
- void compile_and_run(HSQUIRRELVM vm, std::istream& in,
- const std::string& sourcename);
+HSQOBJECT create_thread(HSQUIRRELVM vm);
+SQObject vm_to_object(HSQUIRRELVM vm);
+HSQUIRRELVM object_to_vm(HSQOBJECT object);
- template<typename T>
- void expose_object(HSQUIRRELVM v, SQInteger table_idx, T* object,
- const std::string& name, bool free = false)
- {
- sq_pushstring(v, name.c_str(), -1);
- Scripting::create_squirrel_instance(v, object, free);
+void compile_script(HSQUIRRELVM vm, std::istream& in,
+ const std::string& sourcename);
+void compile_and_run(HSQUIRRELVM vm, std::istream& in,
+ const std::string& sourcename);
+
+template<typename T>
+void expose_object(HSQUIRRELVM v, SQInteger table_idx, T* object,
+ const std::string& name, bool free = false)
+{
+ sq_pushstring(v, name.c_str(), -1);
+ Scripting::create_squirrel_instance(v, object, free);
- if(table_idx < 0)
- table_idx -= 2;
+ if(table_idx < 0)
+ table_idx -= 2;
- // register instance in root table
- if(SQ_FAILED(sq_createslot(v, table_idx))) {
- std::ostringstream msg;
- msg << "Couldn't register object '" << name << "' in squirrel table";
- throw Scripting::SquirrelError(v, msg.str());
- }
+ // register instance in root table
+ if(SQ_FAILED(sq_createslot(v, table_idx))) {
+ std::ostringstream msg;
+ msg << "Couldn't register object '" << name << "' in squirrel table";
+ throw Scripting::SquirrelError(v, msg.str());
}
+}
- static inline void unexpose_object(HSQUIRRELVM v, SQInteger table_idx,
- const std::string& name)
- {
- sq_pushstring(v, name.c_str(), name.length());
+static inline void unexpose_object(HSQUIRRELVM v, SQInteger table_idx,
+ const std::string& name)
+{
+ sq_pushstring(v, name.c_str(), name.length());
- if(table_idx < 0)
- table_idx -= 1;
+ if(table_idx < 0)
+ table_idx -= 1;
- if(SQ_FAILED(sq_deleteslot(v, table_idx, SQFalse))) {
- std::ostringstream msg;
- msg << "Couldn't unregister object '" << name << "' in squirrel root table";
- throw Scripting::SquirrelError(v, msg.str());
- }
+ if(SQ_FAILED(sq_deleteslot(v, table_idx, SQFalse))) {
+ std::ostringstream msg;
+ msg << "Couldn't unregister object '" << name << "' in squirrel root table";
+ throw Scripting::SquirrelError(v, msg.str());
}
+}
- // begin serialization functions
- void store_float(HSQUIRRELVM vm, const char* name, float val);
- void store_int(HSQUIRRELVM vm, const char* name, int val);
- void store_string(HSQUIRRELVM vm, const char* name, const std::string& val);
- void store_bool(HSQUIRRELVM vm, const char* name, bool val);
+// begin serialization functions
+void store_float(HSQUIRRELVM vm, const char* name, float val);
+void store_int(HSQUIRRELVM vm, const char* name, int val);
+void store_string(HSQUIRRELVM vm, const char* name, const std::string& val);
+void store_bool(HSQUIRRELVM vm, const char* name, bool val);
- bool has_float(HSQUIRRELVM vm, const char* name);
- bool has_int(HSQUIRRELVM vm, const char* name);
- bool has_string(HSQUIRRELVM vm, const char* name);
- bool has_bool(HSQUIRRELVM vm, const char* name);
+bool has_float(HSQUIRRELVM vm, const char* name);
+bool has_int(HSQUIRRELVM vm, const char* name);
+bool has_string(HSQUIRRELVM vm, const char* name);
+bool has_bool(HSQUIRRELVM vm, const char* name);
- bool get_float(HSQUIRRELVM vm, const char* name, float& val);
- bool get_int(HSQUIRRELVM vm, const char* name, int& val);
- bool get_string(HSQUIRRELVM vm, const char* name, std::string& val);
- bool get_bool(HSQUIRRELVM vm, const char* name, bool& val);
+bool get_float(HSQUIRRELVM vm, const char* name, float& val);
+bool get_int(HSQUIRRELVM vm, const char* name, int& val);
+bool get_string(HSQUIRRELVM vm, const char* name, std::string& val);
+bool get_bool(HSQUIRRELVM vm, const char* name, bool& val);
- float read_float(HSQUIRRELVM vm, const char* name);
- int read_int(HSQUIRRELVM vm, const char* name);
- std::string read_string(HSQUIRRELVM vm, const char* name);
- bool read_bool(HSQUIRRELVM vm, const char* name);
- // end serialization functions
+float read_float(HSQUIRRELVM vm, const char* name);
+int read_int(HSQUIRRELVM vm, const char* name);
+std::string read_string(HSQUIRRELVM vm, const char* name);
+bool read_bool(HSQUIRRELVM vm, const char* name);
+// end serialization functions
}
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux - Sector Scripting
// Copyright (C) 2006 Wolfgang Becker <uafr@gmx.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __SECTOR_H__
-#define __SECTOR_H__
+#ifndef HEADER_SUPERTUX_SCRIPTING_SSECTOR_HPP
+#define HEADER_SUPERTUX_SCRIPTING_SSECTOR_HPP
-namespace Scripting
-{
+namespace Scripting {
class SSector
{
public:
#ifndef SCRIPTING_API
- virtual ~SSector()
- {}
+ virtual ~SSector()
+ {}
#endif
virtual void set_ambient_light(float red, float green, float blue) = 0;
virtual float get_ambient_red() = 0;
}
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __TEXT_H__
-#define __TEXT_H__
+#ifndef HEADER_SUPERTUX_SCRIPTING_TEXT_HPP
+#define HEADER_SUPERTUX_SCRIPTING_TEXT_HPP
-namespace Scripting
-{
+namespace Scripting {
class Text
{
}
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#include "scripting/thread_queue.hpp"
-#include "thread_queue.hpp"
-#include "squirrel_util.hpp"
-#include "log.hpp"
+#include "scripting/squirrel_util.hpp"
+#include "util/log.hpp"
namespace Scripting
{
HSQUIRRELVM scheduled_vm;
if(sq_gettype(global_vm, -1) == OT_THREAD &&
- SQ_SUCCEEDED(sq_getthread(global_vm, -1, &scheduled_vm))) {
+ SQ_SUCCEEDED(sq_getthread(global_vm, -1, &scheduled_vm))) {
if(SQ_FAILED(sq_wakeupvm(scheduled_vm, SQFalse, SQFalse, SQTrue, SQFalse))) {
log_warning << "Couldn't wakeup scheduled squirrel VM" << std::endl;
}
}
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#ifndef __THREAD_QUEUE_HPP__
-#define __THREAD_QUEUE_HPP__
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_SCRIPTING_THREAD_QUEUE_HPP
+#define HEADER_SUPERTUX_SCRIPTING_THREAD_QUEUE_HPP
-#include <vector>
#include <squirrel.h>
+#include <vector>
-namespace Scripting
-{
+namespace Scripting {
/**
* Keeps a list of SquirrelThreads that wait for a wakeup event
}
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <string>
-#include <stdio.h>
#include "object/thunderstorm.hpp"
-#include "scripting/thunderstorm.hpp"
-#include "math/vector.hpp"
#define NOIMPL log_fatal << __PRETTY_FUNCTION__ << " not implemented."
-namespace Scripting
-{
+namespace Scripting {
- Thunderstorm::Thunderstorm(::Thunderstorm* thunderstorm)
- : thunderstorm(thunderstorm)
- {
- }
+Thunderstorm::Thunderstorm(::Thunderstorm* thunderstorm)
+ : thunderstorm(thunderstorm)
+{
+}
- Thunderstorm::~Thunderstorm()
- {
- }
+Thunderstorm::~Thunderstorm()
+{
+}
- void Thunderstorm::start()
- {
- thunderstorm->start();
- }
+void Thunderstorm::start()
+{
+ thunderstorm->start();
+}
- void Thunderstorm::stop()
- {
- thunderstorm->stop();
- }
+void Thunderstorm::stop()
+{
+ thunderstorm->stop();
+}
- void Thunderstorm::thunder()
- {
- thunderstorm->thunder();
- }
+void Thunderstorm::thunder()
+{
+ thunderstorm->thunder();
+}
- void Thunderstorm::lightning()
- {
- thunderstorm->lightning();
- }
+void Thunderstorm::lightning()
+{
+ thunderstorm->lightning();
+}
- void Thunderstorm::flash()
- {
- thunderstorm->flash();
- }
+void Thunderstorm::flash()
+{
+ thunderstorm->flash();
+}
- void Thunderstorm::electrify()
- {
- thunderstorm->electrify();
- }
+void Thunderstorm::electrify()
+{
+ thunderstorm->electrify();
+}
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __SCRIPTING_THUNDERSTORM_H__
-#define __SCRIPTING_THUNDERSTORM_H__
+#ifndef HEADER_SUPERTUX_SCRIPTING_THUNDERSTORM_HPP
+#define HEADER_SUPERTUX_SCRIPTING_THUNDERSTORM_HPP
#ifndef SCRIPTING_API
class Thunderstorm;
typedef Thunderstorm _Thunderstorm;
#endif
-namespace Scripting
-{
+namespace Scripting {
class Thunderstorm
{
~Thunderstorm();
#endif
- /**
- * Start playing thunder and lightning at configured interval
- */
- void start();
+ /**
+ * Start playing thunder and lightning at configured interval
+ */
+ void start();
- /**
- * Stop playing thunder and lightning at configured interval
- */
- void stop();
+ /**
+ * Stop playing thunder and lightning at configured interval
+ */
+ void stop();
- /**
- * Play thunder
- */
- void thunder();
+ /**
+ * Play thunder
+ */
+ void thunder();
- /**
- * Play lightning, i.e. call flash() and electrify()
- */
- void lightning();
+ /**
+ * Play lightning, i.e. call flash() and electrify()
+ */
+ void lightning();
- /**
- * Display a nice flash
- */
- void flash();
+ /**
+ * Display a nice flash
+ */
+ void flash();
- /**
- * Electrify water throughout the whole sector for a short time
- */
- void electrify();
+ /**
+ * Electrify water throughout the whole sector for a short time
+ */
+ void electrify();
#ifndef SCRIPTING_API
_Thunderstorm* thunderstorm;
}
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <string>
-#include <stdio.h>
#include "object/tilemap.hpp"
#include "scripting/tilemap.hpp"
-#include "math/vector.hpp"
#define NOIMPL log_fatal << __PRETTY_FUNCTION__ << " not implemented."
-namespace Scripting
-{
+namespace Scripting {
- TileMap::TileMap(::TileMap* tilemap)
- : tilemap(tilemap)
- { }
+TileMap::TileMap(::TileMap* tilemap)
+ : tilemap(tilemap)
+{ }
- TileMap::~TileMap()
- { }
+TileMap::~TileMap()
+{ }
- void TileMap::goto_node(int node_no)
- {
- tilemap->goto_node(node_no);
- }
+void TileMap::goto_node(int node_no)
+{
+ tilemap->goto_node(node_no);
+}
- void TileMap::start_moving()
- {
- tilemap->start_moving();
- }
+void TileMap::start_moving()
+{
+ tilemap->start_moving();
+}
- void TileMap::stop_moving()
- {
- tilemap->stop_moving();
- }
+void TileMap::stop_moving()
+{
+ tilemap->stop_moving();
+}
- void TileMap::fade(float alpha, float seconds)
- {
- tilemap->fade(alpha, seconds);
- }
+void TileMap::fade(float alpha, float seconds)
+{
+ tilemap->fade(alpha, seconds);
+}
- void TileMap::set_alpha(float alpha)
- {
- tilemap->set_alpha(alpha);
- }
+void TileMap::set_alpha(float alpha)
+{
+ tilemap->set_alpha(alpha);
+}
- float TileMap::get_alpha()
- {
- return tilemap->get_alpha();
- }
+float TileMap::get_alpha()
+{
+ return tilemap->get_alpha();
+}
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __SCRIPTING_TILEMAP_H__
-#define __SCRIPTING_TILEMAP_H__
+#ifndef HEADER_SUPERTUX_SCRIPTING_TILEMAP_HPP
+#define HEADER_SUPERTUX_SCRIPTING_TILEMAP_HPP
#ifndef SCRIPTING_API
class TileMap;
typedef TileMap _TileMap;
#endif
-namespace Scripting
-{
+namespace Scripting {
class TileMap
{
}
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <algorithm>
-#include "time_scheduler.hpp"
-#include "squirrel_util.hpp"
-#include "squirrel_error.hpp"
-#include "log.hpp"
+#include "scripting/squirrel_util.hpp"
+#include "scripting/time_scheduler.hpp"
+#include "util/log.hpp"
-namespace Scripting
-{
+namespace Scripting {
TimeScheduler* TimeScheduler::instance = NULL;
HSQUIRRELVM scheduled_vm;
if(sq_gettype(global_vm, -1) == OT_THREAD &&
- SQ_SUCCEEDED(sq_getthread(global_vm, -1, &scheduled_vm))) {
+ SQ_SUCCEEDED(sq_getthread(global_vm, -1, &scheduled_vm))) {
if(SQ_FAILED(sq_wakeupvm(scheduled_vm, SQFalse, SQFalse, SQTrue, SQFalse))) {
std::ostringstream msg;
msg << "Error waking VM: ";
sq_getlasterror(scheduled_vm);
if(sq_gettype(scheduled_vm, -1) != OT_STRING) {
- msg << "(no info)";
+ msg << "(no info)";
} else {
- const char* lasterr;
- sq_getstring(scheduled_vm, -1, &lasterr);
- msg << lasterr;
+ const char* lasterr;
+ sq_getstring(scheduled_vm, -1, &lasterr);
+ msg << lasterr;
}
log_warning << msg.str() << std::endl;
sq_pop(scheduled_vm, 1);
}
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-#ifndef __TIME_SCHEDULER_HPP__
-#define __TIME_SCHEDULER_HPP__
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_SCRIPTING_TIME_SCHEDULER_HPP
+#define HEADER_SUPERTUX_SCRIPTING_TIME_SCHEDULER_HPP
#include <vector>
-#include <squirrel.h>
-namespace Scripting
-{
+namespace Scripting {
/**
* This class keeps a list of squirrel threads that are scheduled for a certain
}
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2007 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __SCRIPTING_WILLOWISP_H__
-#define __SCRIPTING_WILLOWISP_H__
+#ifndef HEADER_SUPERTUX_SCRIPTING_WILLOWISP_HPP
+#define HEADER_SUPERTUX_SCRIPTING_WILLOWISP_HPP
-namespace Scripting
-{
+namespace Scripting {
class WillOWisp
{
}
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <string>
-#include <stdio.h>
#include "object/wind.hpp"
#include "scripting/wind.hpp"
-#include "math/vector.hpp"
#define NOIMPL log_fatal << __PRETTY_FUNCTION__ << " not implemented."
-namespace Scripting
-{
+namespace Scripting {
- Wind::Wind(::Wind* wind)
- : wind(wind)
- { }
+Wind::Wind(::Wind* wind)
+ : wind(wind)
+{ }
- Wind::~Wind()
- { }
+Wind::~Wind()
+{ }
- void Wind::start()
- {
- wind->start();
- }
+void Wind::start()
+{
+ wind->start();
+}
- void Wind::stop()
- {
- wind->stop();
- }
+void Wind::stop()
+{
+ wind->stop();
+}
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __SCRIPTING_WIND_H__
-#define __SCRIPTING_WIND_H__
+#ifndef HEADER_SUPERTUX_SCRIPTING_WIND_HPP
+#define HEADER_SUPERTUX_SCRIPTING_WIND_HPP
#ifndef SCRIPTING_API
class Wind;
typedef Wind _Wind;
#endif
-namespace Scripting
-{
+namespace Scripting {
class Wind
{
}
#endif
+
+/* EOF */
* 'src/scripting/wrapper.interface.hpp'
* DO NOT CHANGE
*/
-#include <config.h>
-#include <new>
-#include <assert.h>
-#include <string>
#include <sstream>
-#include <squirrel.h>
-#include "squirrel_error.hpp"
-#include "wrapper.interface.hpp"
-namespace Scripting
-{
-namespace Wrapper
-{
+#include "scripting/squirrel_error.hpp"
+#include "scripting/wrapper.interface.hpp"
-static SQInteger DisplayEffect_release_hook(SQUserPointer ptr, SQInteger )
+namespace Scripting {
+namespace Wrapper {
+
+static SQInteger AmbientSound_release_hook(SQUserPointer ptr, SQInteger )
{
- Scripting::DisplayEffect* _this = reinterpret_cast<Scripting::DisplayEffect*> (ptr);
+ Scripting::AmbientSound* _this = reinterpret_cast<Scripting::AmbientSound*> (ptr);
delete _this;
return 0;
}
-static SQInteger DisplayEffect_fade_out_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'fade_out' called without instance"));
- return SQ_ERROR;
- }
- Scripting::DisplayEffect* _this = reinterpret_cast<Scripting::DisplayEffect*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->fade_out(static_cast<float> (arg0));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'fade_out'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger DisplayEffect_fade_in_wrapper(HSQUIRRELVM vm)
+static SQInteger AmbientSound_set_pos_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'fade_in' called without instance"));
+ sq_throwerror(vm, _SC("'set_pos' called without instance"));
return SQ_ERROR;
}
- Scripting::DisplayEffect* _this = reinterpret_cast<Scripting::DisplayEffect*> (data);
+ Scripting::AmbientSound* _this = reinterpret_cast<Scripting::AmbientSound*> (data);
SQFloat arg0;
if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
sq_throwerror(vm, _SC("Argument 1 not a float"));
return SQ_ERROR;
}
-
- try {
- _this->fade_in(static_cast<float> (arg0));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'fade_in'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger DisplayEffect_set_black_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'set_black' called without instance"));
- return SQ_ERROR;
- }
- Scripting::DisplayEffect* _this = reinterpret_cast<Scripting::DisplayEffect*> (data);
- SQBool arg0;
- if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a bool"));
+ SQFloat arg1;
+ if(SQ_FAILED(sq_getfloat(vm, 3, &arg1))) {
+ sq_throwerror(vm, _SC("Argument 2 not a float"));
return SQ_ERROR;
}
try {
- _this->set_black(arg0 == SQTrue);
+ _this->set_pos(static_cast<float> (arg0), static_cast<float> (arg1));
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_black'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_pos'"));
return SQ_ERROR;
}
}
-static SQInteger DisplayEffect_is_black_wrapper(HSQUIRRELVM vm)
+static SQInteger AmbientSound_get_pos_x_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'is_black' called without instance"));
+ sq_throwerror(vm, _SC("'get_pos_x' called without instance"));
return SQ_ERROR;
}
- Scripting::DisplayEffect* _this = reinterpret_cast<Scripting::DisplayEffect*> (data);
+ Scripting::AmbientSound* _this = reinterpret_cast<Scripting::AmbientSound*> (data);
try {
- bool return_value = _this->is_black();
+ float return_value = _this->get_pos_x();
- sq_pushbool(vm, return_value);
+ sq_pushfloat(vm, return_value);
return 1;
} catch(std::exception& e) {
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'is_black'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger DisplayEffect_sixteen_to_nine_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'sixteen_to_nine' called without instance"));
- return SQ_ERROR;
- }
- Scripting::DisplayEffect* _this = reinterpret_cast<Scripting::DisplayEffect*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->sixteen_to_nine(static_cast<float> (arg0));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'sixteen_to_nine'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_pos_x'"));
return SQ_ERROR;
}
}
-static SQInteger DisplayEffect_four_to_three_wrapper(HSQUIRRELVM vm)
+static SQInteger AmbientSound_get_pos_y_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'four_to_three' called without instance"));
- return SQ_ERROR;
- }
- Scripting::DisplayEffect* _this = reinterpret_cast<Scripting::DisplayEffect*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
+ sq_throwerror(vm, _SC("'get_pos_y' called without instance"));
return SQ_ERROR;
}
+ Scripting::AmbientSound* _this = reinterpret_cast<Scripting::AmbientSound*> (data);
try {
- _this->four_to_three(static_cast<float> (arg0));
+ float return_value = _this->get_pos_y();
- return 0;
+ sq_pushfloat(vm, return_value);
+ return 1;
} catch(std::exception& e) {
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'four_to_three'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_pos_y'"));
return SQ_ERROR;
}
}
-static SQInteger ScriptedObject_release_hook(SQUserPointer ptr, SQInteger )
+static SQInteger Candle_release_hook(SQUserPointer ptr, SQInteger )
{
- Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (ptr);
+ Scripting::Candle* _this = reinterpret_cast<Scripting::Candle*> (ptr);
delete _this;
return 0;
}
-static SQInteger ScriptedObject_set_action_wrapper(HSQUIRRELVM vm)
+static SQInteger Candle_get_burning_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'set_action' called without instance"));
- return SQ_ERROR;
- }
- Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
- const SQChar* arg0;
- if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a string"));
+ sq_throwerror(vm, _SC("'get_burning' called without instance"));
return SQ_ERROR;
}
+ Scripting::Candle* _this = reinterpret_cast<Scripting::Candle*> (data);
try {
- _this->set_action(arg0);
+ bool return_value = _this->get_burning();
- return 0;
+ sq_pushbool(vm, return_value);
+ return 1;
} catch(std::exception& e) {
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_action'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_burning'"));
return SQ_ERROR;
}
}
-static SQInteger ScriptedObject_get_action_wrapper(HSQUIRRELVM vm)
+static SQInteger Candle_set_burning_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'get_action' called without instance"));
+ sq_throwerror(vm, _SC("'set_burning' called without instance"));
+ return SQ_ERROR;
+ }
+ Scripting::Candle* _this = reinterpret_cast<Scripting::Candle*> (data);
+ SQBool arg0;
+ if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
+ sq_throwerror(vm, _SC("Argument 1 not a bool"));
return SQ_ERROR;
}
- Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
try {
- std::string return_value = _this->get_action();
+ _this->set_burning(arg0 == SQTrue);
- sq_pushstring(vm, return_value.c_str(), return_value.size());
- return 1;
+ return 0;
} catch(std::exception& e) {
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_action'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_burning'"));
return SQ_ERROR;
}
}
-static SQInteger ScriptedObject_move_wrapper(HSQUIRRELVM vm)
+static SQInteger DisplayEffect_release_hook(SQUserPointer ptr, SQInteger )
+{
+ Scripting::DisplayEffect* _this = reinterpret_cast<Scripting::DisplayEffect*> (ptr);
+ delete _this;
+ return 0;
+}
+
+static SQInteger DisplayEffect_fade_out_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'move' called without instance"));
+ sq_throwerror(vm, _SC("'fade_out' called without instance"));
return SQ_ERROR;
}
- Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
+ Scripting::DisplayEffect* _this = reinterpret_cast<Scripting::DisplayEffect*> (data);
SQFloat arg0;
if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
sq_throwerror(vm, _SC("Argument 1 not a float"));
return SQ_ERROR;
}
- SQFloat arg1;
- if(SQ_FAILED(sq_getfloat(vm, 3, &arg1))) {
- sq_throwerror(vm, _SC("Argument 2 not a float"));
- return SQ_ERROR;
- }
try {
- _this->move(static_cast<float> (arg0), static_cast<float> (arg1));
+ _this->fade_out(static_cast<float> (arg0));
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'move'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'fade_out'"));
return SQ_ERROR;
}
}
-static SQInteger ScriptedObject_set_pos_wrapper(HSQUIRRELVM vm)
+static SQInteger DisplayEffect_fade_in_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'set_pos' called without instance"));
+ sq_throwerror(vm, _SC("'fade_in' called without instance"));
return SQ_ERROR;
}
- Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
+ Scripting::DisplayEffect* _this = reinterpret_cast<Scripting::DisplayEffect*> (data);
SQFloat arg0;
if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
sq_throwerror(vm, _SC("Argument 1 not a float"));
return SQ_ERROR;
}
- SQFloat arg1;
- if(SQ_FAILED(sq_getfloat(vm, 3, &arg1))) {
- sq_throwerror(vm, _SC("Argument 2 not a float"));
- return SQ_ERROR;
- }
try {
- _this->set_pos(static_cast<float> (arg0), static_cast<float> (arg1));
+ _this->fade_in(static_cast<float> (arg0));
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_pos'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'fade_in'"));
return SQ_ERROR;
}
}
-static SQInteger ScriptedObject_get_pos_x_wrapper(HSQUIRRELVM vm)
+static SQInteger DisplayEffect_set_black_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'get_pos_x' called without instance"));
+ sq_throwerror(vm, _SC("'set_black' called without instance"));
+ return SQ_ERROR;
+ }
+ Scripting::DisplayEffect* _this = reinterpret_cast<Scripting::DisplayEffect*> (data);
+ SQBool arg0;
+ if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
+ sq_throwerror(vm, _SC("Argument 1 not a bool"));
return SQ_ERROR;
}
- Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
try {
- float return_value = _this->get_pos_x();
+ _this->set_black(arg0 == SQTrue);
- sq_pushfloat(vm, return_value);
- return 1;
+ return 0;
} catch(std::exception& e) {
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_pos_x'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_black'"));
return SQ_ERROR;
}
}
-static SQInteger ScriptedObject_get_pos_y_wrapper(HSQUIRRELVM vm)
+static SQInteger DisplayEffect_is_black_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'get_pos_y' called without instance"));
+ sq_throwerror(vm, _SC("'is_black' called without instance"));
return SQ_ERROR;
}
- Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
+ Scripting::DisplayEffect* _this = reinterpret_cast<Scripting::DisplayEffect*> (data);
try {
- float return_value = _this->get_pos_y();
+ bool return_value = _this->is_black();
- sq_pushfloat(vm, return_value);
+ sq_pushbool(vm, return_value);
return 1;
} catch(std::exception& e) {
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_pos_y'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'is_black'"));
return SQ_ERROR;
}
}
-static SQInteger ScriptedObject_set_velocity_wrapper(HSQUIRRELVM vm)
+static SQInteger DisplayEffect_sixteen_to_nine_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'set_velocity' called without instance"));
+ sq_throwerror(vm, _SC("'sixteen_to_nine' called without instance"));
return SQ_ERROR;
}
- Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
+ Scripting::DisplayEffect* _this = reinterpret_cast<Scripting::DisplayEffect*> (data);
SQFloat arg0;
if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
sq_throwerror(vm, _SC("Argument 1 not a float"));
return SQ_ERROR;
}
- SQFloat arg1;
- if(SQ_FAILED(sq_getfloat(vm, 3, &arg1))) {
- sq_throwerror(vm, _SC("Argument 2 not a float"));
- return SQ_ERROR;
- }
try {
- _this->set_velocity(static_cast<float> (arg0), static_cast<float> (arg1));
+ _this->sixteen_to_nine(static_cast<float> (arg0));
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_velocity'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'sixteen_to_nine'"));
return SQ_ERROR;
}
}
-static SQInteger ScriptedObject_get_velocity_x_wrapper(HSQUIRRELVM vm)
+static SQInteger DisplayEffect_four_to_three_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'get_velocity_x' called without instance"));
+ sq_throwerror(vm, _SC("'four_to_three' called without instance"));
+ return SQ_ERROR;
+ }
+ Scripting::DisplayEffect* _this = reinterpret_cast<Scripting::DisplayEffect*> (data);
+ SQFloat arg0;
+ if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
+ sq_throwerror(vm, _SC("Argument 1 not a float"));
return SQ_ERROR;
}
- Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
try {
- float return_value = _this->get_velocity_x();
+ _this->four_to_three(static_cast<float> (arg0));
- sq_pushfloat(vm, return_value);
- return 1;
+ return 0;
} catch(std::exception& e) {
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_velocity_x'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'four_to_three'"));
return SQ_ERROR;
}
}
-static SQInteger ScriptedObject_get_velocity_y_wrapper(HSQUIRRELVM vm)
+static SQInteger FloatingImage_release_hook(SQUserPointer ptr, SQInteger )
{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'get_velocity_y' called without instance"));
+ Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (ptr);
+ delete _this;
+ return 0;
+}
+
+static SQInteger FloatingImage_constructor_wrapper(HSQUIRRELVM vm)
+{
+ const SQChar* arg0;
+ if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
+ sq_throwerror(vm, _SC("Argument 1 not a string"));
return SQ_ERROR;
}
- Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
try {
- float return_value = _this->get_velocity_y();
+ Scripting::FloatingImage* _this = new Scripting::FloatingImage(arg0);
+ if(SQ_FAILED(sq_setinstanceup(vm, 1, _this))) {
+ sq_throwerror(vm, _SC("Couldn't setup instance of 'FloatingImage' class"));
+ return SQ_ERROR;
+ }
+ sq_setreleasehook(vm, 1, FloatingImage_release_hook);
- sq_pushfloat(vm, return_value);
- return 1;
+ return 0;
} catch(std::exception& e) {
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_velocity_y'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'constructor'"));
return SQ_ERROR;
}
}
-static SQInteger ScriptedObject_set_visible_wrapper(HSQUIRRELVM vm)
+static SQInteger FloatingImage_set_layer_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'set_visible' called without instance"));
+ sq_throwerror(vm, _SC("'set_layer' called without instance"));
return SQ_ERROR;
}
- Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
- SQBool arg0;
- if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a bool"));
+ Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
+ SQInteger arg0;
+ if(SQ_FAILED(sq_getinteger(vm, 2, &arg0))) {
+ sq_throwerror(vm, _SC("Argument 1 not an integer"));
return SQ_ERROR;
}
try {
- _this->set_visible(arg0 == SQTrue);
+ _this->set_layer(static_cast<int> (arg0));
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_visible'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_layer'"));
return SQ_ERROR;
}
}
-static SQInteger ScriptedObject_is_visible_wrapper(HSQUIRRELVM vm)
+static SQInteger FloatingImage_get_layer_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'is_visible' called without instance"));
+ sq_throwerror(vm, _SC("'get_layer' called without instance"));
return SQ_ERROR;
}
- Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
+ Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
try {
- bool return_value = _this->is_visible();
+ int return_value = _this->get_layer();
- sq_pushbool(vm, return_value);
+ sq_pushinteger(vm, return_value);
return 1;
} catch(std::exception& e) {
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'is_visible'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_layer'"));
return SQ_ERROR;
}
}
-static SQInteger ScriptedObject_set_solid_wrapper(HSQUIRRELVM vm)
+static SQInteger FloatingImage_set_pos_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'set_solid' called without instance"));
+ sq_throwerror(vm, _SC("'set_pos' called without instance"));
return SQ_ERROR;
}
- Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
- SQBool arg0;
- if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a bool"));
+ Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
+ SQFloat arg0;
+ if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
+ sq_throwerror(vm, _SC("Argument 1 not a float"));
+ return SQ_ERROR;
+ }
+ SQFloat arg1;
+ if(SQ_FAILED(sq_getfloat(vm, 3, &arg1))) {
+ sq_throwerror(vm, _SC("Argument 2 not a float"));
return SQ_ERROR;
}
try {
- _this->set_solid(arg0 == SQTrue);
+ _this->set_pos(static_cast<float> (arg0), static_cast<float> (arg1));
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_solid'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_pos'"));
return SQ_ERROR;
}
}
-static SQInteger ScriptedObject_is_solid_wrapper(HSQUIRRELVM vm)
+static SQInteger FloatingImage_get_pos_x_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'is_solid' called without instance"));
+ sq_throwerror(vm, _SC("'get_pos_x' called without instance"));
return SQ_ERROR;
}
- Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
+ Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
try {
- bool return_value = _this->is_solid();
+ float return_value = _this->get_pos_x();
- sq_pushbool(vm, return_value);
+ sq_pushfloat(vm, return_value);
return 1;
} catch(std::exception& e) {
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'is_solid'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_pos_x'"));
return SQ_ERROR;
}
}
-static SQInteger ScriptedObject_get_name_wrapper(HSQUIRRELVM vm)
+static SQInteger FloatingImage_get_pos_y_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'get_name' called without instance"));
+ sq_throwerror(vm, _SC("'get_pos_y' called without instance"));
return SQ_ERROR;
}
- Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
+ Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
try {
- std::string return_value = _this->get_name();
+ float return_value = _this->get_pos_y();
- sq_pushstring(vm, return_value.c_str(), return_value.size());
+ sq_pushfloat(vm, return_value);
return 1;
} catch(std::exception& e) {
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_name'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_pos_y'"));
return SQ_ERROR;
}
}
-static SQInteger Text_release_hook(SQUserPointer ptr, SQInteger )
-{
- Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (ptr);
- delete _this;
- return 0;
-}
-
-static SQInteger Text_set_text_wrapper(HSQUIRRELVM vm)
+static SQInteger FloatingImage_set_anchor_point_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'set_text' called without instance"));
+ sq_throwerror(vm, _SC("'set_anchor_point' called without instance"));
return SQ_ERROR;
}
- Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (data);
- const SQChar* arg0;
- if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a string"));
+ Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
+ SQInteger arg0;
+ if(SQ_FAILED(sq_getinteger(vm, 2, &arg0))) {
+ sq_throwerror(vm, _SC("Argument 1 not an integer"));
return SQ_ERROR;
}
try {
- _this->set_text(arg0);
+ _this->set_anchor_point(static_cast<int> (arg0));
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_text'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_anchor_point'"));
return SQ_ERROR;
}
}
-static SQInteger Text_set_font_wrapper(HSQUIRRELVM vm)
+static SQInteger FloatingImage_get_anchor_point_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'set_font' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (data);
- const SQChar* arg0;
- if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a string"));
+ sq_throwerror(vm, _SC("'get_anchor_point' called without instance"));
return SQ_ERROR;
}
+ Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
try {
- _this->set_font(arg0);
+ int return_value = _this->get_anchor_point();
- return 0;
+ sq_pushinteger(vm, return_value);
+ return 1;
} catch(std::exception& e) {
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_font'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_anchor_point'"));
return SQ_ERROR;
}
}
-static SQInteger Text_fade_in_wrapper(HSQUIRRELVM vm)
+static SQInteger FloatingImage_set_visible_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'fade_in' called without instance"));
+ sq_throwerror(vm, _SC("'set_visible' called without instance"));
return SQ_ERROR;
}
- Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
+ Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
+ SQBool arg0;
+ if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
+ sq_throwerror(vm, _SC("Argument 1 not a bool"));
return SQ_ERROR;
}
try {
- _this->fade_in(static_cast<float> (arg0));
+ _this->set_visible(arg0 == SQTrue);
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'fade_in'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_visible'"));
return SQ_ERROR;
}
}
-static SQInteger Text_fade_out_wrapper(HSQUIRRELVM vm)
+static SQInteger FloatingImage_get_visible_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'fade_out' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
+ sq_throwerror(vm, _SC("'get_visible' called without instance"));
return SQ_ERROR;
}
+ Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
try {
- _this->fade_out(static_cast<float> (arg0));
+ bool return_value = _this->get_visible();
- return 0;
+ sq_pushbool(vm, return_value);
+ return 1;
} catch(std::exception& e) {
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'fade_out'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_visible'"));
return SQ_ERROR;
}
}
-static SQInteger Text_set_visible_wrapper(HSQUIRRELVM vm)
+static SQInteger FloatingImage_set_action_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'set_visible' called without instance"));
+ sq_throwerror(vm, _SC("'set_action' called without instance"));
return SQ_ERROR;
}
- Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (data);
- SQBool arg0;
- if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a bool"));
+ Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
+ const SQChar* arg0;
+ if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
+ sq_throwerror(vm, _SC("Argument 1 not a string"));
return SQ_ERROR;
}
try {
- _this->set_visible(arg0 == SQTrue);
+ _this->set_action(arg0);
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_visible'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_action'"));
return SQ_ERROR;
}
}
-static SQInteger Text_set_centered_wrapper(HSQUIRRELVM vm)
+static SQInteger FloatingImage_get_action_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'set_centered' called without instance"));
- return SQ_ERROR;
- }
- Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (data);
- SQBool arg0;
- if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a bool"));
+ sq_throwerror(vm, _SC("'get_action' called without instance"));
return SQ_ERROR;
}
+ Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
try {
- _this->set_centered(arg0 == SQTrue);
+ std::string return_value = _this->get_action();
- return 0;
+ sq_pushstring(vm, return_value.c_str(), return_value.size());
+ return 1;
} catch(std::exception& e) {
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_centered'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_action'"));
return SQ_ERROR;
}
}
-static SQInteger Text_set_pos_wrapper(HSQUIRRELVM vm)
+static SQInteger FloatingImage_fade_in_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'set_pos' called without instance"));
+ sq_throwerror(vm, _SC("'fade_in' called without instance"));
return SQ_ERROR;
}
- Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (data);
+ Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
SQFloat arg0;
if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
sq_throwerror(vm, _SC("Argument 1 not a float"));
return SQ_ERROR;
}
- SQFloat arg1;
- if(SQ_FAILED(sq_getfloat(vm, 3, &arg1))) {
- sq_throwerror(vm, _SC("Argument 2 not a float"));
- return SQ_ERROR;
- }
try {
- _this->set_pos(static_cast<float> (arg0), static_cast<float> (arg1));
+ _this->fade_in(static_cast<float> (arg0));
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_pos'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'fade_in'"));
return SQ_ERROR;
}
}
-static SQInteger Text_get_pos_x_wrapper(HSQUIRRELVM vm)
+static SQInteger FloatingImage_fade_out_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'get_pos_x' called without instance"));
+ sq_throwerror(vm, _SC("'fade_out' called without instance"));
+ return SQ_ERROR;
+ }
+ Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
+ SQFloat arg0;
+ if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
+ sq_throwerror(vm, _SC("Argument 1 not a float"));
return SQ_ERROR;
}
- Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (data);
try {
- float return_value = _this->get_pos_x();
+ _this->fade_out(static_cast<float> (arg0));
- sq_pushfloat(vm, return_value);
- return 1;
+ return 0;
} catch(std::exception& e) {
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_pos_x'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'fade_out'"));
return SQ_ERROR;
}
}
-static SQInteger Text_get_pos_y_wrapper(HSQUIRRELVM vm)
+static SQInteger LevelTime_release_hook(SQUserPointer ptr, SQInteger )
+{
+ Scripting::LevelTime* _this = reinterpret_cast<Scripting::LevelTime*> (ptr);
+ delete _this;
+ return 0;
+}
+
+static SQInteger LevelTime_start_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'get_pos_y' called without instance"));
+ sq_throwerror(vm, _SC("'start' called without instance"));
return SQ_ERROR;
}
- Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (data);
+ Scripting::LevelTime* _this = reinterpret_cast<Scripting::LevelTime*> (data);
try {
- float return_value = _this->get_pos_y();
+ _this->start();
+
+ return 0;
+
+ } catch(std::exception& e) {
+ sq_throwerror(vm, e.what());
+ return SQ_ERROR;
+ } catch(...) {
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'start'"));
+ return SQ_ERROR;
+ }
+
+}
+
+static SQInteger LevelTime_stop_wrapper(HSQUIRRELVM vm)
+{
+ SQUserPointer data;
+ if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
+ sq_throwerror(vm, _SC("'stop' called without instance"));
+ return SQ_ERROR;
+ }
+ Scripting::LevelTime* _this = reinterpret_cast<Scripting::LevelTime*> (data);
+
+ try {
+ _this->stop();
+
+ return 0;
+
+ } catch(std::exception& e) {
+ sq_throwerror(vm, e.what());
+ return SQ_ERROR;
+ } catch(...) {
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'stop'"));
+ return SQ_ERROR;
+ }
+
+}
+
+static SQInteger LevelTime_get_time_wrapper(HSQUIRRELVM vm)
+{
+ SQUserPointer data;
+ if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
+ sq_throwerror(vm, _SC("'get_time' called without instance"));
+ return SQ_ERROR;
+ }
+ Scripting::LevelTime* _this = reinterpret_cast<Scripting::LevelTime*> (data);
+
+ try {
+ float return_value = _this->get_time();
sq_pushfloat(vm, return_value);
return 1;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_pos_y'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_time'"));
return SQ_ERROR;
}
}
-static SQInteger Text_set_anchor_point_wrapper(HSQUIRRELVM vm)
+static SQInteger LevelTime_set_time_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'set_anchor_point' called without instance"));
+ sq_throwerror(vm, _SC("'set_time' called without instance"));
return SQ_ERROR;
}
- Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (data);
+ Scripting::LevelTime* _this = reinterpret_cast<Scripting::LevelTime*> (data);
+ SQFloat arg0;
+ if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
+ sq_throwerror(vm, _SC("Argument 1 not a float"));
+ return SQ_ERROR;
+ }
+
+ try {
+ _this->set_time(static_cast<float> (arg0));
+
+ return 0;
+
+ } catch(std::exception& e) {
+ sq_throwerror(vm, e.what());
+ return SQ_ERROR;
+ } catch(...) {
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_time'"));
+ return SQ_ERROR;
+ }
+
+}
+
+static SQInteger Platform_release_hook(SQUserPointer ptr, SQInteger )
+{
+ Scripting::Platform* _this = reinterpret_cast<Scripting::Platform*> (ptr);
+ delete _this;
+ return 0;
+}
+
+static SQInteger Platform_goto_node_wrapper(HSQUIRRELVM vm)
+{
+ SQUserPointer data;
+ if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
+ sq_throwerror(vm, _SC("'goto_node' called without instance"));
+ return SQ_ERROR;
+ }
+ Scripting::Platform* _this = reinterpret_cast<Scripting::Platform*> (data);
SQInteger arg0;
if(SQ_FAILED(sq_getinteger(vm, 2, &arg0))) {
sq_throwerror(vm, _SC("Argument 1 not an integer"));
}
try {
- _this->set_anchor_point(static_cast<int> (arg0));
+ _this->goto_node(static_cast<int> (arg0));
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_anchor_point'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'goto_node'"));
return SQ_ERROR;
}
}
-static SQInteger Text_get_anchor_point_wrapper(HSQUIRRELVM vm)
+static SQInteger Platform_start_moving_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'get_anchor_point' called without instance"));
+ sq_throwerror(vm, _SC("'start_moving' called without instance"));
return SQ_ERROR;
}
- Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (data);
+ Scripting::Platform* _this = reinterpret_cast<Scripting::Platform*> (data);
try {
- int return_value = _this->get_anchor_point();
+ _this->start_moving();
- sq_pushinteger(vm, return_value);
- return 1;
+ return 0;
} catch(std::exception& e) {
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_anchor_point'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'start_moving'"));
+ return SQ_ERROR;
+ }
+
+}
+
+static SQInteger Platform_stop_moving_wrapper(HSQUIRRELVM vm)
+{
+ SQUserPointer data;
+ if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
+ sq_throwerror(vm, _SC("'stop_moving' called without instance"));
+ return SQ_ERROR;
+ }
+ Scripting::Platform* _this = reinterpret_cast<Scripting::Platform*> (data);
+
+ try {
+ _this->stop_moving();
+
+ return 0;
+
+ } catch(std::exception& e) {
+ sq_throwerror(vm, e.what());
+ return SQ_ERROR;
+ } catch(...) {
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'stop_moving'"));
return SQ_ERROR;
}
}
-static SQInteger FloatingImage_release_hook(SQUserPointer ptr, SQInteger )
+static SQInteger ScriptedObject_release_hook(SQUserPointer ptr, SQInteger )
{
- Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (ptr);
+ Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (ptr);
delete _this;
return 0;
}
-static SQInteger FloatingImage_constructor_wrapper(HSQUIRRELVM vm)
+static SQInteger ScriptedObject_set_action_wrapper(HSQUIRRELVM vm)
{
+ SQUserPointer data;
+ if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
+ sq_throwerror(vm, _SC("'set_action' called without instance"));
+ return SQ_ERROR;
+ }
+ Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
const SQChar* arg0;
if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
sq_throwerror(vm, _SC("Argument 1 not a string"));
}
try {
- Scripting::FloatingImage* _this = new Scripting::FloatingImage(arg0);
- if(SQ_FAILED(sq_setinstanceup(vm, 1, _this))) {
- sq_throwerror(vm, _SC("Couldn't setup instance of 'FloatingImage' class"));
- return SQ_ERROR;
- }
- sq_setreleasehook(vm, 1, FloatingImage_release_hook);
+ _this->set_action(arg0);
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'constructor'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_action'"));
return SQ_ERROR;
}
}
-static SQInteger FloatingImage_set_layer_wrapper(HSQUIRRELVM vm)
+static SQInteger ScriptedObject_get_action_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'set_layer' called without instance"));
- return SQ_ERROR;
- }
- Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
- SQInteger arg0;
- if(SQ_FAILED(sq_getinteger(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not an integer"));
+ sq_throwerror(vm, _SC("'get_action' called without instance"));
return SQ_ERROR;
}
+ Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
try {
- _this->set_layer(static_cast<int> (arg0));
+ std::string return_value = _this->get_action();
- return 0;
+ sq_pushstring(vm, return_value.c_str(), return_value.size());
+ return 1;
} catch(std::exception& e) {
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_layer'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_action'"));
return SQ_ERROR;
}
}
-static SQInteger FloatingImage_get_layer_wrapper(HSQUIRRELVM vm)
+static SQInteger ScriptedObject_move_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'get_layer' called without instance"));
+ sq_throwerror(vm, _SC("'move' called without instance"));
+ return SQ_ERROR;
+ }
+ Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
+ SQFloat arg0;
+ if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
+ sq_throwerror(vm, _SC("Argument 1 not a float"));
+ return SQ_ERROR;
+ }
+ SQFloat arg1;
+ if(SQ_FAILED(sq_getfloat(vm, 3, &arg1))) {
+ sq_throwerror(vm, _SC("Argument 2 not a float"));
return SQ_ERROR;
}
- Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
try {
- int return_value = _this->get_layer();
+ _this->move(static_cast<float> (arg0), static_cast<float> (arg1));
- sq_pushinteger(vm, return_value);
- return 1;
+ return 0;
} catch(std::exception& e) {
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_layer'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'move'"));
return SQ_ERROR;
}
}
-static SQInteger FloatingImage_set_pos_wrapper(HSQUIRRELVM vm)
+static SQInteger ScriptedObject_set_pos_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
sq_throwerror(vm, _SC("'set_pos' called without instance"));
return SQ_ERROR;
}
- Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
+ Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
SQFloat arg0;
if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
sq_throwerror(vm, _SC("Argument 1 not a float"));
}
-static SQInteger FloatingImage_get_pos_x_wrapper(HSQUIRRELVM vm)
+static SQInteger ScriptedObject_get_pos_x_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
sq_throwerror(vm, _SC("'get_pos_x' called without instance"));
return SQ_ERROR;
}
- Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
+ Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
try {
float return_value = _this->get_pos_x();
}
-static SQInteger FloatingImage_get_pos_y_wrapper(HSQUIRRELVM vm)
+static SQInteger ScriptedObject_get_pos_y_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
sq_throwerror(vm, _SC("'get_pos_y' called without instance"));
return SQ_ERROR;
}
- Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
+ Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
try {
float return_value = _this->get_pos_y();
}
-static SQInteger FloatingImage_set_anchor_point_wrapper(HSQUIRRELVM vm)
+static SQInteger ScriptedObject_set_velocity_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'set_anchor_point' called without instance"));
+ sq_throwerror(vm, _SC("'set_velocity' called without instance"));
return SQ_ERROR;
}
- Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
- SQInteger arg0;
- if(SQ_FAILED(sq_getinteger(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not an integer"));
+ Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
+ SQFloat arg0;
+ if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
+ sq_throwerror(vm, _SC("Argument 1 not a float"));
+ return SQ_ERROR;
+ }
+ SQFloat arg1;
+ if(SQ_FAILED(sq_getfloat(vm, 3, &arg1))) {
+ sq_throwerror(vm, _SC("Argument 2 not a float"));
return SQ_ERROR;
}
try {
- _this->set_anchor_point(static_cast<int> (arg0));
+ _this->set_velocity(static_cast<float> (arg0), static_cast<float> (arg1));
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_anchor_point'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_velocity'"));
return SQ_ERROR;
}
}
-static SQInteger FloatingImage_get_anchor_point_wrapper(HSQUIRRELVM vm)
+static SQInteger ScriptedObject_get_velocity_x_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'get_anchor_point' called without instance"));
+ sq_throwerror(vm, _SC("'get_velocity_x' called without instance"));
return SQ_ERROR;
}
- Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
+ Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
try {
- int return_value = _this->get_anchor_point();
+ float return_value = _this->get_velocity_x();
- sq_pushinteger(vm, return_value);
+ sq_pushfloat(vm, return_value);
return 1;
} catch(std::exception& e) {
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_anchor_point'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_velocity_x'"));
return SQ_ERROR;
}
}
-static SQInteger FloatingImage_set_visible_wrapper(HSQUIRRELVM vm)
+static SQInteger ScriptedObject_get_velocity_y_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'set_visible' called without instance"));
- return SQ_ERROR;
- }
- Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
- SQBool arg0;
- if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a bool"));
+ sq_throwerror(vm, _SC("'get_velocity_y' called without instance"));
return SQ_ERROR;
}
+ Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
try {
- _this->set_visible(arg0 == SQTrue);
+ float return_value = _this->get_velocity_y();
- return 0;
+ sq_pushfloat(vm, return_value);
+ return 1;
} catch(std::exception& e) {
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_visible'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_velocity_y'"));
return SQ_ERROR;
}
}
-static SQInteger FloatingImage_get_visible_wrapper(HSQUIRRELVM vm)
+static SQInteger ScriptedObject_set_visible_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'get_visible' called without instance"));
+ sq_throwerror(vm, _SC("'set_visible' called without instance"));
+ return SQ_ERROR;
+ }
+ Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
+ SQBool arg0;
+ if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
+ sq_throwerror(vm, _SC("Argument 1 not a bool"));
return SQ_ERROR;
}
- Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
try {
- bool return_value = _this->get_visible();
+ _this->set_visible(arg0 == SQTrue);
- sq_pushbool(vm, return_value);
- return 1;
+ return 0;
} catch(std::exception& e) {
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_visible'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_visible'"));
return SQ_ERROR;
}
}
-static SQInteger FloatingImage_set_action_wrapper(HSQUIRRELVM vm)
+static SQInteger ScriptedObject_is_visible_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'set_action' called without instance"));
- return SQ_ERROR;
- }
- Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
- const SQChar* arg0;
- if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a string"));
+ sq_throwerror(vm, _SC("'is_visible' called without instance"));
return SQ_ERROR;
}
+ Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
try {
- _this->set_action(arg0);
+ bool return_value = _this->is_visible();
- return 0;
+ sq_pushbool(vm, return_value);
+ return 1;
} catch(std::exception& e) {
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_action'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'is_visible'"));
return SQ_ERROR;
}
}
-static SQInteger FloatingImage_get_action_wrapper(HSQUIRRELVM vm)
+static SQInteger ScriptedObject_set_solid_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'get_action' called without instance"));
+ sq_throwerror(vm, _SC("'set_solid' called without instance"));
+ return SQ_ERROR;
+ }
+ Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
+ SQBool arg0;
+ if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
+ sq_throwerror(vm, _SC("Argument 1 not a bool"));
return SQ_ERROR;
}
- Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
try {
- std::string return_value = _this->get_action();
+ _this->set_solid(arg0 == SQTrue);
- sq_pushstring(vm, return_value.c_str(), return_value.size());
- return 1;
+ return 0;
} catch(std::exception& e) {
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_action'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_solid'"));
return SQ_ERROR;
}
}
-static SQInteger FloatingImage_fade_in_wrapper(HSQUIRRELVM vm)
+static SQInteger ScriptedObject_is_solid_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'fade_in' called without instance"));
- return SQ_ERROR;
- }
- Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
+ sq_throwerror(vm, _SC("'is_solid' called without instance"));
return SQ_ERROR;
}
+ Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
try {
- _this->fade_in(static_cast<float> (arg0));
+ bool return_value = _this->is_solid();
- return 0;
+ sq_pushbool(vm, return_value);
+ return 1;
} catch(std::exception& e) {
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'fade_in'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'is_solid'"));
return SQ_ERROR;
}
}
-static SQInteger FloatingImage_fade_out_wrapper(HSQUIRRELVM vm)
+static SQInteger ScriptedObject_get_name_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'fade_out' called without instance"));
- return SQ_ERROR;
- }
- Scripting::FloatingImage* _this = reinterpret_cast<Scripting::FloatingImage*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
+ sq_throwerror(vm, _SC("'get_name' called without instance"));
return SQ_ERROR;
}
+ Scripting::ScriptedObject* _this = reinterpret_cast<Scripting::ScriptedObject*> (data);
try {
- _this->fade_out(static_cast<float> (arg0));
+ std::string return_value = _this->get_name();
- return 0;
+ sq_pushstring(vm, return_value.c_str(), return_value.size());
+ return 1;
} catch(std::exception& e) {
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'fade_out'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_name'"));
return SQ_ERROR;
}
}
-static SQInteger Platform_release_hook(SQUserPointer ptr, SQInteger )
+static SQInteger SSector_release_hook(SQUserPointer ptr, SQInteger )
{
- Scripting::Platform* _this = reinterpret_cast<Scripting::Platform*> (ptr);
+ Scripting::SSector* _this = reinterpret_cast<Scripting::SSector*> (ptr);
delete _this;
return 0;
}
-static SQInteger Platform_goto_node_wrapper(HSQUIRRELVM vm)
+static SQInteger SSector_set_ambient_light_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'goto_node' called without instance"));
+ sq_throwerror(vm, _SC("'set_ambient_light' called without instance"));
return SQ_ERROR;
}
- Scripting::Platform* _this = reinterpret_cast<Scripting::Platform*> (data);
- SQInteger arg0;
- if(SQ_FAILED(sq_getinteger(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not an integer"));
+ Scripting::SSector* _this = reinterpret_cast<Scripting::SSector*> (data);
+ SQFloat arg0;
+ if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
+ sq_throwerror(vm, _SC("Argument 1 not a float"));
+ return SQ_ERROR;
+ }
+ SQFloat arg1;
+ if(SQ_FAILED(sq_getfloat(vm, 3, &arg1))) {
+ sq_throwerror(vm, _SC("Argument 2 not a float"));
+ return SQ_ERROR;
+ }
+ SQFloat arg2;
+ if(SQ_FAILED(sq_getfloat(vm, 4, &arg2))) {
+ sq_throwerror(vm, _SC("Argument 3 not a float"));
return SQ_ERROR;
}
try {
- _this->goto_node(static_cast<int> (arg0));
+ _this->set_ambient_light(static_cast<float> (arg0), static_cast<float> (arg1), static_cast<float> (arg2));
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'goto_node'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_ambient_light'"));
return SQ_ERROR;
}
}
-static SQInteger Platform_start_moving_wrapper(HSQUIRRELVM vm)
+static SQInteger SSector_get_ambient_red_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'start_moving' called without instance"));
+ sq_throwerror(vm, _SC("'get_ambient_red' called without instance"));
return SQ_ERROR;
}
- Scripting::Platform* _this = reinterpret_cast<Scripting::Platform*> (data);
+ Scripting::SSector* _this = reinterpret_cast<Scripting::SSector*> (data);
try {
- _this->start_moving();
+ float return_value = _this->get_ambient_red();
- return 0;
+ sq_pushfloat(vm, return_value);
+ return 1;
} catch(std::exception& e) {
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'start_moving'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_ambient_red'"));
return SQ_ERROR;
}
}
-static SQInteger Platform_stop_moving_wrapper(HSQUIRRELVM vm)
+static SQInteger SSector_get_ambient_green_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'stop_moving' called without instance"));
+ sq_throwerror(vm, _SC("'get_ambient_green' called without instance"));
return SQ_ERROR;
}
- Scripting::Platform* _this = reinterpret_cast<Scripting::Platform*> (data);
+ Scripting::SSector* _this = reinterpret_cast<Scripting::SSector*> (data);
try {
- _this->stop_moving();
+ float return_value = _this->get_ambient_green();
- return 0;
+ sq_pushfloat(vm, return_value);
+ return 1;
} catch(std::exception& e) {
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'stop_moving'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_ambient_green'"));
return SQ_ERROR;
}
}
-static SQInteger Candle_release_hook(SQUserPointer ptr, SQInteger )
-{
- Scripting::Candle* _this = reinterpret_cast<Scripting::Candle*> (ptr);
- delete _this;
- return 0;
-}
-
-static SQInteger Candle_get_burning_wrapper(HSQUIRRELVM vm)
+static SQInteger SSector_get_ambient_blue_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'get_burning' called without instance"));
+ sq_throwerror(vm, _SC("'get_ambient_blue' called without instance"));
return SQ_ERROR;
}
- Scripting::Candle* _this = reinterpret_cast<Scripting::Candle*> (data);
+ Scripting::SSector* _this = reinterpret_cast<Scripting::SSector*> (data);
try {
- bool return_value = _this->get_burning();
+ float return_value = _this->get_ambient_blue();
- sq_pushbool(vm, return_value);
+ sq_pushfloat(vm, return_value);
return 1;
} catch(std::exception& e) {
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_burning'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_ambient_blue'"));
return SQ_ERROR;
}
}
-static SQInteger Candle_set_burning_wrapper(HSQUIRRELVM vm)
+static SQInteger SSector_set_gravity_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'set_burning' called without instance"));
+ sq_throwerror(vm, _SC("'set_gravity' called without instance"));
return SQ_ERROR;
}
- Scripting::Candle* _this = reinterpret_cast<Scripting::Candle*> (data);
- SQBool arg0;
- if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a bool"));
+ Scripting::SSector* _this = reinterpret_cast<Scripting::SSector*> (data);
+ SQFloat arg0;
+ if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
+ sq_throwerror(vm, _SC("Argument 1 not a float"));
return SQ_ERROR;
}
try {
- _this->set_burning(arg0 == SQTrue);
+ _this->set_gravity(static_cast<float> (arg0));
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_burning'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_gravity'"));
return SQ_ERROR;
}
}
-static SQInteger Wind_release_hook(SQUserPointer ptr, SQInteger )
+static SQInteger Text_release_hook(SQUserPointer ptr, SQInteger )
{
- Scripting::Wind* _this = reinterpret_cast<Scripting::Wind*> (ptr);
+ Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (ptr);
delete _this;
return 0;
}
-static SQInteger Wind_start_wrapper(HSQUIRRELVM vm)
+static SQInteger Text_set_text_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'start' called without instance"));
+ sq_throwerror(vm, _SC("'set_text' called without instance"));
+ return SQ_ERROR;
+ }
+ Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (data);
+ const SQChar* arg0;
+ if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
+ sq_throwerror(vm, _SC("Argument 1 not a string"));
return SQ_ERROR;
}
- Scripting::Wind* _this = reinterpret_cast<Scripting::Wind*> (data);
try {
- _this->start();
+ _this->set_text(arg0);
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'start'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_text'"));
return SQ_ERROR;
}
}
-static SQInteger Wind_stop_wrapper(HSQUIRRELVM vm)
+static SQInteger Text_set_font_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'stop' called without instance"));
+ sq_throwerror(vm, _SC("'set_font' called without instance"));
+ return SQ_ERROR;
+ }
+ Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (data);
+ const SQChar* arg0;
+ if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
+ sq_throwerror(vm, _SC("Argument 1 not a string"));
return SQ_ERROR;
}
- Scripting::Wind* _this = reinterpret_cast<Scripting::Wind*> (data);
try {
- _this->stop();
+ _this->set_font(arg0);
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'stop'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_font'"));
return SQ_ERROR;
}
}
-static SQInteger AmbientSound_release_hook(SQUserPointer ptr, SQInteger )
-{
- Scripting::AmbientSound* _this = reinterpret_cast<Scripting::AmbientSound*> (ptr);
- delete _this;
- return 0;
-}
-
-static SQInteger AmbientSound_set_pos_wrapper(HSQUIRRELVM vm)
+static SQInteger Text_fade_in_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'set_pos' called without instance"));
+ sq_throwerror(vm, _SC("'fade_in' called without instance"));
return SQ_ERROR;
}
- Scripting::AmbientSound* _this = reinterpret_cast<Scripting::AmbientSound*> (data);
+ Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (data);
SQFloat arg0;
if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
sq_throwerror(vm, _SC("Argument 1 not a float"));
return SQ_ERROR;
}
- SQFloat arg1;
- if(SQ_FAILED(sq_getfloat(vm, 3, &arg1))) {
- sq_throwerror(vm, _SC("Argument 2 not a float"));
- return SQ_ERROR;
- }
+
+ try {
+ _this->fade_in(static_cast<float> (arg0));
+
+ return 0;
+
+ } catch(std::exception& e) {
+ sq_throwerror(vm, e.what());
+ return SQ_ERROR;
+ } catch(...) {
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'fade_in'"));
+ return SQ_ERROR;
+ }
+
+}
+
+static SQInteger Text_fade_out_wrapper(HSQUIRRELVM vm)
+{
+ SQUserPointer data;
+ if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
+ sq_throwerror(vm, _SC("'fade_out' called without instance"));
+ return SQ_ERROR;
+ }
+ Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (data);
+ SQFloat arg0;
+ if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
+ sq_throwerror(vm, _SC("Argument 1 not a float"));
+ return SQ_ERROR;
+ }
+
+ try {
+ _this->fade_out(static_cast<float> (arg0));
+
+ return 0;
+
+ } catch(std::exception& e) {
+ sq_throwerror(vm, e.what());
+ return SQ_ERROR;
+ } catch(...) {
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'fade_out'"));
+ return SQ_ERROR;
+ }
+
+}
+
+static SQInteger Text_set_visible_wrapper(HSQUIRRELVM vm)
+{
+ SQUserPointer data;
+ if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
+ sq_throwerror(vm, _SC("'set_visible' called without instance"));
+ return SQ_ERROR;
+ }
+ Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (data);
+ SQBool arg0;
+ if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
+ sq_throwerror(vm, _SC("Argument 1 not a bool"));
+ return SQ_ERROR;
+ }
+
+ try {
+ _this->set_visible(arg0 == SQTrue);
+
+ return 0;
+
+ } catch(std::exception& e) {
+ sq_throwerror(vm, e.what());
+ return SQ_ERROR;
+ } catch(...) {
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_visible'"));
+ return SQ_ERROR;
+ }
+
+}
+
+static SQInteger Text_set_centered_wrapper(HSQUIRRELVM vm)
+{
+ SQUserPointer data;
+ if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
+ sq_throwerror(vm, _SC("'set_centered' called without instance"));
+ return SQ_ERROR;
+ }
+ Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (data);
+ SQBool arg0;
+ if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
+ sq_throwerror(vm, _SC("Argument 1 not a bool"));
+ return SQ_ERROR;
+ }
+
+ try {
+ _this->set_centered(arg0 == SQTrue);
+
+ return 0;
+
+ } catch(std::exception& e) {
+ sq_throwerror(vm, e.what());
+ return SQ_ERROR;
+ } catch(...) {
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_centered'"));
+ return SQ_ERROR;
+ }
+
+}
+
+static SQInteger Text_set_pos_wrapper(HSQUIRRELVM vm)
+{
+ SQUserPointer data;
+ if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
+ sq_throwerror(vm, _SC("'set_pos' called without instance"));
+ return SQ_ERROR;
+ }
+ Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (data);
+ SQFloat arg0;
+ if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
+ sq_throwerror(vm, _SC("Argument 1 not a float"));
+ return SQ_ERROR;
+ }
+ SQFloat arg1;
+ if(SQ_FAILED(sq_getfloat(vm, 3, &arg1))) {
+ sq_throwerror(vm, _SC("Argument 2 not a float"));
+ return SQ_ERROR;
+ }
try {
_this->set_pos(static_cast<float> (arg0), static_cast<float> (arg1));
}
-static SQInteger AmbientSound_get_pos_x_wrapper(HSQUIRRELVM vm)
+static SQInteger Text_get_pos_x_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
sq_throwerror(vm, _SC("'get_pos_x' called without instance"));
return SQ_ERROR;
}
- Scripting::AmbientSound* _this = reinterpret_cast<Scripting::AmbientSound*> (data);
+ Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (data);
try {
float return_value = _this->get_pos_x();
}
-static SQInteger AmbientSound_get_pos_y_wrapper(HSQUIRRELVM vm)
+static SQInteger Text_get_pos_y_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
sq_throwerror(vm, _SC("'get_pos_y' called without instance"));
return SQ_ERROR;
}
- Scripting::AmbientSound* _this = reinterpret_cast<Scripting::AmbientSound*> (data);
+ Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (data);
try {
float return_value = _this->get_pos_y();
}
+static SQInteger Text_set_anchor_point_wrapper(HSQUIRRELVM vm)
+{
+ SQUserPointer data;
+ if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
+ sq_throwerror(vm, _SC("'set_anchor_point' called without instance"));
+ return SQ_ERROR;
+ }
+ Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (data);
+ SQInteger arg0;
+ if(SQ_FAILED(sq_getinteger(vm, 2, &arg0))) {
+ sq_throwerror(vm, _SC("Argument 1 not an integer"));
+ return SQ_ERROR;
+ }
+
+ try {
+ _this->set_anchor_point(static_cast<int> (arg0));
+
+ return 0;
+
+ } catch(std::exception& e) {
+ sq_throwerror(vm, e.what());
+ return SQ_ERROR;
+ } catch(...) {
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_anchor_point'"));
+ return SQ_ERROR;
+ }
+
+}
+
+static SQInteger Text_get_anchor_point_wrapper(HSQUIRRELVM vm)
+{
+ SQUserPointer data;
+ if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
+ sq_throwerror(vm, _SC("'get_anchor_point' called without instance"));
+ return SQ_ERROR;
+ }
+ Scripting::Text* _this = reinterpret_cast<Scripting::Text*> (data);
+
+ try {
+ int return_value = _this->get_anchor_point();
+
+ sq_pushinteger(vm, return_value);
+ return 1;
+
+ } catch(std::exception& e) {
+ sq_throwerror(vm, e.what());
+ return SQ_ERROR;
+ } catch(...) {
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_anchor_point'"));
+ return SQ_ERROR;
+ }
+
+}
+
static SQInteger Thunderstorm_release_hook(SQUserPointer ptr, SQInteger )
{
Scripting::Thunderstorm* _this = reinterpret_cast<Scripting::Thunderstorm*> (ptr);
}
-static SQInteger SSector_release_hook(SQUserPointer ptr, SQInteger )
+static SQInteger WillOWisp_release_hook(SQUserPointer ptr, SQInteger )
{
- Scripting::SSector* _this = reinterpret_cast<Scripting::SSector*> (ptr);
+ Scripting::WillOWisp* _this = reinterpret_cast<Scripting::WillOWisp*> (ptr);
delete _this;
return 0;
}
-static SQInteger SSector_set_ambient_light_wrapper(HSQUIRRELVM vm)
+static SQInteger WillOWisp_goto_node_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'set_ambient_light' called without instance"));
- return SQ_ERROR;
- }
- Scripting::SSector* _this = reinterpret_cast<Scripting::SSector*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
- SQFloat arg1;
- if(SQ_FAILED(sq_getfloat(vm, 3, &arg1))) {
- sq_throwerror(vm, _SC("Argument 2 not a float"));
+ sq_throwerror(vm, _SC("'goto_node' called without instance"));
return SQ_ERROR;
}
- SQFloat arg2;
- if(SQ_FAILED(sq_getfloat(vm, 4, &arg2))) {
- sq_throwerror(vm, _SC("Argument 3 not a float"));
+ Scripting::WillOWisp* _this = reinterpret_cast<Scripting::WillOWisp*> (data);
+ SQInteger arg0;
+ if(SQ_FAILED(sq_getinteger(vm, 2, &arg0))) {
+ sq_throwerror(vm, _SC("Argument 1 not an integer"));
return SQ_ERROR;
}
try {
- _this->set_ambient_light(static_cast<float> (arg0), static_cast<float> (arg1), static_cast<float> (arg2));
+ _this->goto_node(static_cast<int> (arg0));
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_ambient_light'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'goto_node'"));
return SQ_ERROR;
}
}
-static SQInteger SSector_get_ambient_red_wrapper(HSQUIRRELVM vm)
+static SQInteger WillOWisp_set_state_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'get_ambient_red' called without instance"));
+ sq_throwerror(vm, _SC("'set_state' called without instance"));
+ return SQ_ERROR;
+ }
+ Scripting::WillOWisp* _this = reinterpret_cast<Scripting::WillOWisp*> (data);
+ const SQChar* arg0;
+ if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
+ sq_throwerror(vm, _SC("Argument 1 not a string"));
return SQ_ERROR;
}
- Scripting::SSector* _this = reinterpret_cast<Scripting::SSector*> (data);
try {
- float return_value = _this->get_ambient_red();
+ _this->set_state(arg0);
- sq_pushfloat(vm, return_value);
- return 1;
+ return 0;
} catch(std::exception& e) {
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_ambient_red'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_state'"));
return SQ_ERROR;
}
}
-static SQInteger SSector_get_ambient_green_wrapper(HSQUIRRELVM vm)
+static SQInteger WillOWisp_start_moving_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'get_ambient_green' called without instance"));
+ sq_throwerror(vm, _SC("'start_moving' called without instance"));
return SQ_ERROR;
}
- Scripting::SSector* _this = reinterpret_cast<Scripting::SSector*> (data);
+ Scripting::WillOWisp* _this = reinterpret_cast<Scripting::WillOWisp*> (data);
try {
- float return_value = _this->get_ambient_green();
+ _this->start_moving();
- sq_pushfloat(vm, return_value);
- return 1;
+ return 0;
} catch(std::exception& e) {
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_ambient_green'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'start_moving'"));
return SQ_ERROR;
}
}
-static SQInteger SSector_get_ambient_blue_wrapper(HSQUIRRELVM vm)
+static SQInteger WillOWisp_stop_moving_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'get_ambient_blue' called without instance"));
+ sq_throwerror(vm, _SC("'stop_moving' called without instance"));
return SQ_ERROR;
}
- Scripting::SSector* _this = reinterpret_cast<Scripting::SSector*> (data);
+ Scripting::WillOWisp* _this = reinterpret_cast<Scripting::WillOWisp*> (data);
try {
- float return_value = _this->get_ambient_blue();
+ _this->stop_moving();
- sq_pushfloat(vm, return_value);
- return 1;
+ return 0;
} catch(std::exception& e) {
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_ambient_blue'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger SSector_set_gravity_wrapper(HSQUIRRELVM vm)
-{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'set_gravity' called without instance"));
- return SQ_ERROR;
- }
- Scripting::SSector* _this = reinterpret_cast<Scripting::SSector*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
-
- try {
- _this->set_gravity(static_cast<float> (arg0));
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_gravity'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'stop_moving'"));
return SQ_ERROR;
}
}
-static SQInteger LevelTime_release_hook(SQUserPointer ptr, SQInteger )
+static SQInteger Wind_release_hook(SQUserPointer ptr, SQInteger )
{
- Scripting::LevelTime* _this = reinterpret_cast<Scripting::LevelTime*> (ptr);
+ Scripting::Wind* _this = reinterpret_cast<Scripting::Wind*> (ptr);
delete _this;
return 0;
}
-static SQInteger LevelTime_start_wrapper(HSQUIRRELVM vm)
+static SQInteger Wind_start_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
sq_throwerror(vm, _SC("'start' called without instance"));
return SQ_ERROR;
}
- Scripting::LevelTime* _this = reinterpret_cast<Scripting::LevelTime*> (data);
+ Scripting::Wind* _this = reinterpret_cast<Scripting::Wind*> (data);
try {
_this->start();
}
-static SQInteger LevelTime_stop_wrapper(HSQUIRRELVM vm)
+static SQInteger Wind_stop_wrapper(HSQUIRRELVM vm)
{
SQUserPointer data;
if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
sq_throwerror(vm, _SC("'stop' called without instance"));
return SQ_ERROR;
}
- Scripting::LevelTime* _this = reinterpret_cast<Scripting::LevelTime*> (data);
+ Scripting::Wind* _this = reinterpret_cast<Scripting::Wind*> (data);
try {
_this->stop();
}
-static SQInteger LevelTime_get_time_wrapper(HSQUIRRELVM vm)
+static SQInteger display_wrapper(HSQUIRRELVM vm)
{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'get_time' called without instance"));
- return SQ_ERROR;
- }
- Scripting::LevelTime* _this = reinterpret_cast<Scripting::LevelTime*> (data);
+ return Scripting::display(vm);
+}
+
+static SQInteger print_stacktrace_wrapper(HSQUIRRELVM vm)
+{
+ HSQUIRRELVM arg0 = vm;
try {
- float return_value = _this->get_time();
+ Scripting::print_stacktrace(arg0);
- sq_pushfloat(vm, return_value);
- return 1;
+ return 0;
} catch(std::exception& e) {
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'get_time'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'print_stacktrace'"));
return SQ_ERROR;
}
}
-static SQInteger LevelTime_set_time_wrapper(HSQUIRRELVM vm)
+static SQInteger get_current_thread_wrapper(HSQUIRRELVM vm)
{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'set_time' called without instance"));
- return SQ_ERROR;
- }
- Scripting::LevelTime* _this = reinterpret_cast<Scripting::LevelTime*> (data);
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
+ return Scripting::get_current_thread(vm);
+}
+
+static SQInteger display_text_file_wrapper(HSQUIRRELVM vm)
+{
+ const SQChar* arg0;
+ if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
+ sq_throwerror(vm, _SC("Argument 1 not a string"));
return SQ_ERROR;
}
try {
- _this->set_time(static_cast<float> (arg0));
+ Scripting::display_text_file(arg0);
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_time'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'display_text_file'"));
return SQ_ERROR;
}
}
-static SQInteger WillOWisp_release_hook(SQUserPointer ptr, SQInteger )
-{
- Scripting::WillOWisp* _this = reinterpret_cast<Scripting::WillOWisp*> (ptr);
- delete _this;
- return 0;
-}
-
-static SQInteger WillOWisp_goto_node_wrapper(HSQUIRRELVM vm)
+static SQInteger load_worldmap_wrapper(HSQUIRRELVM vm)
{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'goto_node' called without instance"));
- return SQ_ERROR;
- }
- Scripting::WillOWisp* _this = reinterpret_cast<Scripting::WillOWisp*> (data);
- SQInteger arg0;
- if(SQ_FAILED(sq_getinteger(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not an integer"));
+ const SQChar* arg0;
+ if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
+ sq_throwerror(vm, _SC("Argument 1 not a string"));
return SQ_ERROR;
}
try {
- _this->goto_node(static_cast<int> (arg0));
+ Scripting::load_worldmap(arg0);
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'goto_node'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'load_worldmap'"));
return SQ_ERROR;
}
}
-static SQInteger WillOWisp_set_state_wrapper(HSQUIRRELVM vm)
+static SQInteger load_level_wrapper(HSQUIRRELVM vm)
{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'set_state' called without instance"));
- return SQ_ERROR;
- }
- Scripting::WillOWisp* _this = reinterpret_cast<Scripting::WillOWisp*> (data);
const SQChar* arg0;
if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
sq_throwerror(vm, _SC("Argument 1 not a string"));
}
try {
- _this->set_state(arg0);
+ Scripting::load_level(arg0);
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_state'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'load_level'"));
return SQ_ERROR;
}
}
-static SQInteger WillOWisp_start_moving_wrapper(HSQUIRRELVM vm)
+static SQInteger wait_wrapper(HSQUIRRELVM vm)
{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'start_moving' called without instance"));
+ HSQUIRRELVM arg0 = vm;
+ SQFloat arg1;
+ if(SQ_FAILED(sq_getfloat(vm, 2, &arg1))) {
+ sq_throwerror(vm, _SC("Argument 1 not a float"));
return SQ_ERROR;
}
- Scripting::WillOWisp* _this = reinterpret_cast<Scripting::WillOWisp*> (data);
try {
- _this->start_moving();
+ Scripting::wait(arg0, static_cast<float> (arg1));
- return 0;
+ return sq_suspendvm(vm);
} catch(std::exception& e) {
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'start_moving'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'wait'"));
return SQ_ERROR;
}
}
-static SQInteger WillOWisp_stop_moving_wrapper(HSQUIRRELVM vm)
+static SQInteger wait_for_screenswitch_wrapper(HSQUIRRELVM vm)
{
- SQUserPointer data;
- if(SQ_FAILED(sq_getinstanceup(vm, 1, &data, 0)) || !data) {
- sq_throwerror(vm, _SC("'stop_moving' called without instance"));
+ HSQUIRRELVM arg0 = vm;
+
+ try {
+ Scripting::wait_for_screenswitch(arg0);
+
+ return sq_suspendvm(vm);
+
+ } catch(std::exception& e) {
+ sq_throwerror(vm, e.what());
+ return SQ_ERROR;
+ } catch(...) {
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'wait_for_screenswitch'"));
return SQ_ERROR;
}
- Scripting::WillOWisp* _this = reinterpret_cast<Scripting::WillOWisp*> (data);
+
+}
+
+static SQInteger exit_screen_wrapper(HSQUIRRELVM vm)
+{
+ (void) vm;
try {
- _this->stop_moving();
+ Scripting::exit_screen();
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'stop_moving'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'exit_screen'"));
return SQ_ERROR;
}
}
-static SQInteger Level_finish_wrapper(HSQUIRRELVM vm)
+static SQInteger fadeout_screen_wrapper(HSQUIRRELVM vm)
{
- SQBool arg0;
- if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a bool"));
+ SQFloat arg0;
+ if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
+ sq_throwerror(vm, _SC("Argument 1 not a float"));
return SQ_ERROR;
}
try {
- Scripting::Level_finish(arg0 == SQTrue);
+ Scripting::fadeout_screen(static_cast<float> (arg0));
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'Level_finish'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'fadeout_screen'"));
return SQ_ERROR;
}
}
-static SQInteger Level_spawn_wrapper(HSQUIRRELVM vm)
+static SQInteger shrink_screen_wrapper(HSQUIRRELVM vm)
{
- const SQChar* arg0;
- if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a string"));
+ SQFloat arg0;
+ if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
+ sq_throwerror(vm, _SC("Argument 1 not a float"));
return SQ_ERROR;
}
- const SQChar* arg1;
- if(SQ_FAILED(sq_getstring(vm, 3, &arg1))) {
- sq_throwerror(vm, _SC("Argument 2 not a string"));
+ SQFloat arg1;
+ if(SQ_FAILED(sq_getfloat(vm, 3, &arg1))) {
+ sq_throwerror(vm, _SC("Argument 2 not a float"));
+ return SQ_ERROR;
+ }
+ SQFloat arg2;
+ if(SQ_FAILED(sq_getfloat(vm, 4, &arg2))) {
+ sq_throwerror(vm, _SC("Argument 3 not a float"));
return SQ_ERROR;
}
try {
- Scripting::Level_spawn(arg0, arg1);
+ Scripting::shrink_screen(static_cast<float> (arg0), static_cast<float> (arg1), static_cast<float> (arg2));
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'Level_spawn'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'shrink_screen'"));
return SQ_ERROR;
}
}
-static SQInteger Level_flip_vertically_wrapper(HSQUIRRELVM vm)
+static SQInteger abort_screenfade_wrapper(HSQUIRRELVM vm)
{
(void) vm;
try {
- Scripting::Level_flip_vertically();
+ Scripting::abort_screenfade();
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'Level_flip_vertically'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'abort_screenfade'"));
return SQ_ERROR;
}
}
-static SQInteger Level_toggle_pause_wrapper(HSQUIRRELVM vm)
+static SQInteger translate_wrapper(HSQUIRRELVM vm)
{
- (void) vm;
+ const SQChar* arg0;
+ if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
+ sq_throwerror(vm, _SC("Argument 1 not a string"));
+ return SQ_ERROR;
+ }
try {
- Scripting::Level_toggle_pause();
+ std::string return_value = Scripting::translate(arg0);
- return 0;
+ sq_pushstring(vm, return_value.c_str(), return_value.size());
+ return 1;
} catch(std::exception& e) {
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'Level_toggle_pause'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'translate'"));
return SQ_ERROR;
}
}
-static SQInteger Level_edit_wrapper(HSQUIRRELVM vm)
+static SQInteger import_wrapper(HSQUIRRELVM vm)
{
- SQBool arg0;
- if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a bool"));
+ HSQUIRRELVM arg0 = vm;
+ const SQChar* arg1;
+ if(SQ_FAILED(sq_getstring(vm, 2, &arg1))) {
+ sq_throwerror(vm, _SC("Argument 1 not a string"));
return SQ_ERROR;
}
try {
- Scripting::Level_edit(arg0 == SQTrue);
+ Scripting::import(arg0, arg1);
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'Level_edit'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'import'"));
return SQ_ERROR;
}
}
-static SQInteger display_wrapper(HSQUIRRELVM vm)
-{
- return Scripting::display(vm);
-}
-
-static SQInteger print_stacktrace_wrapper(HSQUIRRELVM vm)
+static SQInteger save_state_wrapper(HSQUIRRELVM vm)
{
- HSQUIRRELVM arg0 = vm;
+ (void) vm;
try {
- Scripting::print_stacktrace(arg0);
+ Scripting::save_state();
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'print_stacktrace'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'save_state'"));
return SQ_ERROR;
}
}
-static SQInteger get_current_thread_wrapper(HSQUIRRELVM vm)
+static SQInteger update_worldmap_wrapper(HSQUIRRELVM vm)
{
- return Scripting::get_current_thread(vm);
-}
-
-static SQInteger display_text_file_wrapper(HSQUIRRELVM vm)
-{
- const SQChar* arg0;
- if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a string"));
- return SQ_ERROR;
- }
+ (void) vm;
try {
- Scripting::display_text_file(arg0);
+ Scripting::update_worldmap();
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'display_text_file'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'update_worldmap'"));
return SQ_ERROR;
}
}
-static SQInteger load_worldmap_wrapper(HSQUIRRELVM vm)
+static SQInteger debug_collrects_wrapper(HSQUIRRELVM vm)
{
- const SQChar* arg0;
- if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a string"));
+ SQBool arg0;
+ if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
+ sq_throwerror(vm, _SC("Argument 1 not a bool"));
return SQ_ERROR;
}
try {
- Scripting::load_worldmap(arg0);
+ Scripting::debug_collrects(arg0 == SQTrue);
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'load_worldmap'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'debug_collrects'"));
return SQ_ERROR;
}
}
-static SQInteger load_level_wrapper(HSQUIRRELVM vm)
+static SQInteger debug_show_fps_wrapper(HSQUIRRELVM vm)
{
- const SQChar* arg0;
- if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a string"));
+ SQBool arg0;
+ if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
+ sq_throwerror(vm, _SC("Argument 1 not a bool"));
return SQ_ERROR;
}
try {
- Scripting::load_level(arg0);
+ Scripting::debug_show_fps(arg0 == SQTrue);
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'load_level'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'debug_show_fps'"));
return SQ_ERROR;
}
}
-static SQInteger wait_wrapper(HSQUIRRELVM vm)
+static SQInteger debug_draw_solids_only_wrapper(HSQUIRRELVM vm)
{
- HSQUIRRELVM arg0 = vm;
- SQFloat arg1;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg1))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
+ SQBool arg0;
+ if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
+ sq_throwerror(vm, _SC("Argument 1 not a bool"));
return SQ_ERROR;
}
try {
- Scripting::wait(arg0, static_cast<float> (arg1));
+ Scripting::debug_draw_solids_only(arg0 == SQTrue);
- return sq_suspendvm(vm);
+ return 0;
} catch(std::exception& e) {
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'wait'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'debug_draw_solids_only'"));
return SQ_ERROR;
}
}
-static SQInteger wait_for_screenswitch_wrapper(HSQUIRRELVM vm)
+static SQInteger debug_worldmap_ghost_wrapper(HSQUIRRELVM vm)
{
- HSQUIRRELVM arg0 = vm;
+ SQBool arg0;
+ if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
+ sq_throwerror(vm, _SC("Argument 1 not a bool"));
+ return SQ_ERROR;
+ }
try {
- Scripting::wait_for_screenswitch(arg0);
+ Scripting::debug_worldmap_ghost(arg0 == SQTrue);
- return sq_suspendvm(vm);
+ return 0;
} catch(std::exception& e) {
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'wait_for_screenswitch'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'debug_worldmap_ghost'"));
return SQ_ERROR;
}
}
-static SQInteger exit_screen_wrapper(HSQUIRRELVM vm)
+static SQInteger play_music_wrapper(HSQUIRRELVM vm)
{
- (void) vm;
+ const SQChar* arg0;
+ if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
+ sq_throwerror(vm, _SC("Argument 1 not a string"));
+ return SQ_ERROR;
+ }
try {
- Scripting::exit_screen();
+ Scripting::play_music(arg0);
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'exit_screen'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'play_music'"));
return SQ_ERROR;
}
}
-static SQInteger fadeout_screen_wrapper(HSQUIRRELVM vm)
+static SQInteger play_sound_wrapper(HSQUIRRELVM vm)
{
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
+ const SQChar* arg0;
+ if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
+ sq_throwerror(vm, _SC("Argument 1 not a string"));
return SQ_ERROR;
}
try {
- Scripting::fadeout_screen(static_cast<float> (arg0));
+ Scripting::play_sound(arg0);
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'fadeout_screen'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'play_sound'"));
return SQ_ERROR;
}
}
-static SQInteger shrink_screen_wrapper(HSQUIRRELVM vm)
+static SQInteger set_game_speed_wrapper(HSQUIRRELVM vm)
{
SQFloat arg0;
if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
sq_throwerror(vm, _SC("Argument 1 not a float"));
return SQ_ERROR;
}
- SQFloat arg1;
- if(SQ_FAILED(sq_getfloat(vm, 3, &arg1))) {
- sq_throwerror(vm, _SC("Argument 2 not a float"));
+
+ try {
+ Scripting::set_game_speed(static_cast<float> (arg0));
+
+ return 0;
+
+ } catch(std::exception& e) {
+ sq_throwerror(vm, e.what());
return SQ_ERROR;
- }
- SQFloat arg2;
- if(SQ_FAILED(sq_getfloat(vm, 4, &arg2))) {
- sq_throwerror(vm, _SC("Argument 3 not a float"));
+ } catch(...) {
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_game_speed'"));
return SQ_ERROR;
}
+}
+
+static SQInteger grease_wrapper(HSQUIRRELVM vm)
+{
+ (void) vm;
+
try {
- Scripting::shrink_screen(static_cast<float> (arg0), static_cast<float> (arg1), static_cast<float> (arg2));
+ Scripting::grease();
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'shrink_screen'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'grease'"));
return SQ_ERROR;
}
}
-static SQInteger abort_screenfade_wrapper(HSQUIRRELVM vm)
+static SQInteger invincible_wrapper(HSQUIRRELVM vm)
{
(void) vm;
try {
- Scripting::abort_screenfade();
+ Scripting::invincible();
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'abort_screenfade'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'invincible'"));
return SQ_ERROR;
}
}
-static SQInteger translate_wrapper(HSQUIRRELVM vm)
+static SQInteger ghost_wrapper(HSQUIRRELVM vm)
{
- const SQChar* arg0;
- if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a string"));
- return SQ_ERROR;
- }
+ (void) vm;
try {
- std::string return_value = Scripting::translate(arg0);
+ Scripting::ghost();
- sq_pushstring(vm, return_value.c_str(), return_value.size());
- return 1;
+ return 0;
} catch(std::exception& e) {
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'translate'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'ghost'"));
return SQ_ERROR;
}
}
-static SQInteger import_wrapper(HSQUIRRELVM vm)
+static SQInteger mortal_wrapper(HSQUIRRELVM vm)
{
- HSQUIRRELVM arg0 = vm;
- const SQChar* arg1;
- if(SQ_FAILED(sq_getstring(vm, 2, &arg1))) {
- sq_throwerror(vm, _SC("Argument 1 not a string"));
- return SQ_ERROR;
- }
+ (void) vm;
try {
- Scripting::import(arg0, arg1);
+ Scripting::mortal();
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'import'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'mortal'"));
return SQ_ERROR;
}
}
-static SQInteger save_state_wrapper(HSQUIRRELVM vm)
+static SQInteger restart_wrapper(HSQUIRRELVM vm)
{
(void) vm;
try {
- Scripting::save_state();
+ Scripting::restart();
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'save_state'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'restart'"));
return SQ_ERROR;
}
}
-static SQInteger update_worldmap_wrapper(HSQUIRRELVM vm)
+static SQInteger whereami_wrapper(HSQUIRRELVM vm)
{
(void) vm;
try {
- Scripting::update_worldmap();
+ Scripting::whereami();
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'update_worldmap'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'whereami'"));
return SQ_ERROR;
}
}
-static SQInteger debug_collrects_wrapper(HSQUIRRELVM vm)
+static SQInteger gotoend_wrapper(HSQUIRRELVM vm)
{
- SQBool arg0;
- if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a bool"));
- return SQ_ERROR;
- }
+ (void) vm;
try {
- Scripting::debug_collrects(arg0 == SQTrue);
+ Scripting::gotoend();
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'debug_collrects'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'gotoend'"));
return SQ_ERROR;
}
}
-static SQInteger debug_show_fps_wrapper(HSQUIRRELVM vm)
+static SQInteger camera_wrapper(HSQUIRRELVM vm)
{
- SQBool arg0;
- if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a bool"));
- return SQ_ERROR;
- }
+ (void) vm;
try {
- Scripting::debug_show_fps(arg0 == SQTrue);
+ Scripting::camera();
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'debug_show_fps'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'camera'"));
return SQ_ERROR;
}
}
-static SQInteger debug_draw_solids_only_wrapper(HSQUIRRELVM vm)
+static SQInteger set_gamma_wrapper(HSQUIRRELVM vm)
{
- SQBool arg0;
- if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a bool"));
+ SQFloat arg0;
+ if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
+ sq_throwerror(vm, _SC("Argument 1 not a float"));
return SQ_ERROR;
}
try {
- Scripting::debug_draw_solids_only(arg0 == SQTrue);
+ Scripting::set_gamma(static_cast<float> (arg0));
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'debug_draw_solids_only'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_gamma'"));
return SQ_ERROR;
}
}
-static SQInteger debug_worldmap_ghost_wrapper(HSQUIRRELVM vm)
+static SQInteger quit_wrapper(HSQUIRRELVM vm)
{
- SQBool arg0;
- if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a bool"));
- return SQ_ERROR;
- }
+ (void) vm;
try {
- Scripting::debug_worldmap_ghost(arg0 == SQTrue);
+ Scripting::quit();
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'debug_worldmap_ghost'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'quit'"));
return SQ_ERROR;
}
}
-static SQInteger play_music_wrapper(HSQUIRRELVM vm)
+static SQInteger rand_wrapper(HSQUIRRELVM vm)
{
- const SQChar* arg0;
- if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a string"));
- return SQ_ERROR;
- }
try {
- Scripting::play_music(arg0);
+ int return_value = Scripting::rand();
- return 0;
+ sq_pushinteger(vm, return_value);
+ return 1;
} catch(std::exception& e) {
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'play_music'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'rand'"));
return SQ_ERROR;
}
}
-static SQInteger play_sound_wrapper(HSQUIRRELVM vm)
+static SQInteger record_demo_wrapper(HSQUIRRELVM vm)
{
const SQChar* arg0;
if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
}
try {
- Scripting::play_sound(arg0);
+ Scripting::record_demo(arg0);
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'play_sound'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'record_demo'"));
return SQ_ERROR;
}
}
-static SQInteger set_game_speed_wrapper(HSQUIRRELVM vm)
+static SQInteger play_demo_wrapper(HSQUIRRELVM vm)
{
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
+ const SQChar* arg0;
+ if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
+ sq_throwerror(vm, _SC("Argument 1 not a string"));
return SQ_ERROR;
}
try {
- Scripting::set_game_speed(static_cast<float> (arg0));
+ Scripting::play_demo(arg0);
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_game_speed'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'play_demo'"));
return SQ_ERROR;
}
}
-static SQInteger grease_wrapper(HSQUIRRELVM vm)
+static SQInteger Level_finish_wrapper(HSQUIRRELVM vm)
{
- (void) vm;
+ SQBool arg0;
+ if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
+ sq_throwerror(vm, _SC("Argument 1 not a bool"));
+ return SQ_ERROR;
+ }
try {
- Scripting::grease();
+ Scripting::Level_finish(arg0 == SQTrue);
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'grease'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'Level_finish'"));
return SQ_ERROR;
}
}
-static SQInteger invincible_wrapper(HSQUIRRELVM vm)
+static SQInteger Level_spawn_wrapper(HSQUIRRELVM vm)
{
- (void) vm;
-
- try {
- Scripting::invincible();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'invincible'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger ghost_wrapper(HSQUIRRELVM vm)
-{
- (void) vm;
-
- try {
- Scripting::ghost();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'ghost'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger mortal_wrapper(HSQUIRRELVM vm)
-{
- (void) vm;
-
- try {
- Scripting::mortal();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'mortal'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger restart_wrapper(HSQUIRRELVM vm)
-{
- (void) vm;
-
- try {
- Scripting::restart();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'restart'"));
+ const SQChar* arg0;
+ if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
+ sq_throwerror(vm, _SC("Argument 1 not a string"));
return SQ_ERROR;
}
-
-}
-
-static SQInteger whereami_wrapper(HSQUIRRELVM vm)
-{
- (void) vm;
-
- try {
- Scripting::whereami();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'whereami'"));
+ const SQChar* arg1;
+ if(SQ_FAILED(sq_getstring(vm, 3, &arg1))) {
+ sq_throwerror(vm, _SC("Argument 2 not a string"));
return SQ_ERROR;
}
-}
-
-static SQInteger gotoend_wrapper(HSQUIRRELVM vm)
-{
- (void) vm;
-
try {
- Scripting::gotoend();
+ Scripting::Level_spawn(arg0, arg1);
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'gotoend'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'Level_spawn'"));
return SQ_ERROR;
}
}
-static SQInteger camera_wrapper(HSQUIRRELVM vm)
+static SQInteger Level_flip_vertically_wrapper(HSQUIRRELVM vm)
{
(void) vm;
try {
- Scripting::camera();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'camera'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger set_gamma_wrapper(HSQUIRRELVM vm)
-{
- SQFloat arg0;
- if(SQ_FAILED(sq_getfloat(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a float"));
- return SQ_ERROR;
- }
-
- try {
- Scripting::set_gamma(static_cast<float> (arg0));
+ Scripting::Level_flip_vertically();
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'set_gamma'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'Level_flip_vertically'"));
return SQ_ERROR;
}
}
-static SQInteger quit_wrapper(HSQUIRRELVM vm)
+static SQInteger Level_toggle_pause_wrapper(HSQUIRRELVM vm)
{
(void) vm;
try {
- Scripting::quit();
-
- return 0;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'quit'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger rand_wrapper(HSQUIRRELVM vm)
-{
-
- try {
- int return_value = Scripting::rand();
-
- sq_pushinteger(vm, return_value);
- return 1;
-
- } catch(std::exception& e) {
- sq_throwerror(vm, e.what());
- return SQ_ERROR;
- } catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'rand'"));
- return SQ_ERROR;
- }
-
-}
-
-static SQInteger record_demo_wrapper(HSQUIRRELVM vm)
-{
- const SQChar* arg0;
- if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a string"));
- return SQ_ERROR;
- }
-
- try {
- Scripting::record_demo(arg0);
+ Scripting::Level_toggle_pause();
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'record_demo'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'Level_toggle_pause'"));
return SQ_ERROR;
}
}
-static SQInteger play_demo_wrapper(HSQUIRRELVM vm)
+static SQInteger Level_edit_wrapper(HSQUIRRELVM vm)
{
- const SQChar* arg0;
- if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
- sq_throwerror(vm, _SC("Argument 1 not a string"));
+ SQBool arg0;
+ if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) {
+ sq_throwerror(vm, _SC("Argument 1 not a bool"));
return SQ_ERROR;
}
try {
- Scripting::play_demo(arg0);
+ Scripting::Level_edit(arg0 == SQTrue);
return 0;
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
- sq_throwerror(vm, _SC("Unexpected exception while executing function 'play_demo'"));
+ sq_throwerror(vm, _SC("Unexpected exception while executing function 'Level_edit'"));
return SQ_ERROR;
}
}
} // end of namespace Wrapper
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::DisplayEffect* object, bool setup_releasehook)
+void create_squirrel_instance(HSQUIRRELVM v, Scripting::AmbientSound* object, bool setup_releasehook)
{
using namespace Wrapper;
sq_pushroottable(v);
- sq_pushstring(v, "DisplayEffect", -1);
+ sq_pushstring(v, "AmbientSound", -1);
if(SQ_FAILED(sq_get(v, -2))) {
std::ostringstream msg;
- msg << "Couldn't resolved squirrel type 'DisplayEffect'";
+ msg << "Couldn't resolved squirrel type 'AmbientSound'";
throw SquirrelError(v, msg.str());
}
if(SQ_FAILED(sq_createinstance(v, -1)) || SQ_FAILED(sq_setinstanceup(v, -1, object))) {
std::ostringstream msg;
- msg << "Couldn't setup squirrel instance for object of type 'DisplayEffect'";
+ msg << "Couldn't setup squirrel instance for object of type 'AmbientSound'";
throw SquirrelError(v, msg.str());
}
sq_remove(v, -2); // remove object name
if(setup_releasehook) {
- sq_setreleasehook(v, -1, DisplayEffect_release_hook);
+ sq_setreleasehook(v, -1, AmbientSound_release_hook);
}
sq_remove(v, -2); // remove root table
sq_remove(v, -2); // remove root table
}
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::ScriptedObject* object, bool setup_releasehook)
+void create_squirrel_instance(HSQUIRRELVM v, Scripting::Candle* object, bool setup_releasehook)
{
using namespace Wrapper;
sq_pushroottable(v);
- sq_pushstring(v, "ScriptedObject", -1);
+ sq_pushstring(v, "Candle", -1);
if(SQ_FAILED(sq_get(v, -2))) {
std::ostringstream msg;
- msg << "Couldn't resolved squirrel type 'ScriptedObject'";
+ msg << "Couldn't resolved squirrel type 'Candle'";
throw SquirrelError(v, msg.str());
}
if(SQ_FAILED(sq_createinstance(v, -1)) || SQ_FAILED(sq_setinstanceup(v, -1, object))) {
std::ostringstream msg;
- msg << "Couldn't setup squirrel instance for object of type 'ScriptedObject'";
+ msg << "Couldn't setup squirrel instance for object of type 'Candle'";
throw SquirrelError(v, msg.str());
}
sq_remove(v, -2); // remove object name
if(setup_releasehook) {
- sq_setreleasehook(v, -1, ScriptedObject_release_hook);
+ sq_setreleasehook(v, -1, Candle_release_hook);
}
sq_remove(v, -2); // remove root table
}
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::Text* object, bool setup_releasehook)
+void create_squirrel_instance(HSQUIRRELVM v, Scripting::DisplayEffect* object, bool setup_releasehook)
{
using namespace Wrapper;
sq_pushroottable(v);
- sq_pushstring(v, "Text", -1);
+ sq_pushstring(v, "DisplayEffect", -1);
if(SQ_FAILED(sq_get(v, -2))) {
std::ostringstream msg;
- msg << "Couldn't resolved squirrel type 'Text'";
+ msg << "Couldn't resolved squirrel type 'DisplayEffect'";
throw SquirrelError(v, msg.str());
}
if(SQ_FAILED(sq_createinstance(v, -1)) || SQ_FAILED(sq_setinstanceup(v, -1, object))) {
std::ostringstream msg;
- msg << "Couldn't setup squirrel instance for object of type 'Text'";
+ msg << "Couldn't setup squirrel instance for object of type 'DisplayEffect'";
throw SquirrelError(v, msg.str());
}
sq_remove(v, -2); // remove object name
if(setup_releasehook) {
- sq_setreleasehook(v, -1, Text_release_hook);
+ sq_setreleasehook(v, -1, DisplayEffect_release_hook);
}
sq_remove(v, -2); // remove root table
}
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::Player* object, bool setup_releasehook)
+void create_squirrel_instance(HSQUIRRELVM v, Scripting::FloatingImage* object, bool setup_releasehook)
{
using namespace Wrapper;
sq_pushroottable(v);
- sq_pushstring(v, "Player", -1);
+ sq_pushstring(v, "FloatingImage", -1);
if(SQ_FAILED(sq_get(v, -2))) {
std::ostringstream msg;
- msg << "Couldn't resolved squirrel type 'Player'";
+ msg << "Couldn't resolved squirrel type 'FloatingImage'";
throw SquirrelError(v, msg.str());
}
if(SQ_FAILED(sq_createinstance(v, -1)) || SQ_FAILED(sq_setinstanceup(v, -1, object))) {
std::ostringstream msg;
- msg << "Couldn't setup squirrel instance for object of type 'Player'";
+ msg << "Couldn't setup squirrel instance for object of type 'FloatingImage'";
throw SquirrelError(v, msg.str());
}
sq_remove(v, -2); // remove object name
if(setup_releasehook) {
- sq_setreleasehook(v, -1, Player_release_hook);
+ sq_setreleasehook(v, -1, FloatingImage_release_hook);
}
sq_remove(v, -2); // remove root table
}
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::FloatingImage* object, bool setup_releasehook)
+void create_squirrel_instance(HSQUIRRELVM v, Scripting::LevelTime* object, bool setup_releasehook)
{
using namespace Wrapper;
sq_pushroottable(v);
- sq_pushstring(v, "FloatingImage", -1);
+ sq_pushstring(v, "LevelTime", -1);
if(SQ_FAILED(sq_get(v, -2))) {
std::ostringstream msg;
- msg << "Couldn't resolved squirrel type 'FloatingImage'";
+ msg << "Couldn't resolved squirrel type 'LevelTime'";
throw SquirrelError(v, msg.str());
}
if(SQ_FAILED(sq_createinstance(v, -1)) || SQ_FAILED(sq_setinstanceup(v, -1, object))) {
std::ostringstream msg;
- msg << "Couldn't setup squirrel instance for object of type 'FloatingImage'";
+ msg << "Couldn't setup squirrel instance for object of type 'LevelTime'";
throw SquirrelError(v, msg.str());
}
sq_remove(v, -2); // remove object name
if(setup_releasehook) {
- sq_setreleasehook(v, -1, FloatingImage_release_hook);
+ sq_setreleasehook(v, -1, LevelTime_release_hook);
}
sq_remove(v, -2); // remove root table
sq_remove(v, -2); // remove root table
}
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::Candle* object, bool setup_releasehook)
+void create_squirrel_instance(HSQUIRRELVM v, Scripting::Player* object, bool setup_releasehook)
{
using namespace Wrapper;
sq_pushroottable(v);
- sq_pushstring(v, "Candle", -1);
+ sq_pushstring(v, "Player", -1);
if(SQ_FAILED(sq_get(v, -2))) {
std::ostringstream msg;
- msg << "Couldn't resolved squirrel type 'Candle'";
+ msg << "Couldn't resolved squirrel type 'Player'";
throw SquirrelError(v, msg.str());
}
if(SQ_FAILED(sq_createinstance(v, -1)) || SQ_FAILED(sq_setinstanceup(v, -1, object))) {
std::ostringstream msg;
- msg << "Couldn't setup squirrel instance for object of type 'Candle'";
+ msg << "Couldn't setup squirrel instance for object of type 'Player'";
throw SquirrelError(v, msg.str());
}
sq_remove(v, -2); // remove object name
if(setup_releasehook) {
- sq_setreleasehook(v, -1, Candle_release_hook);
+ sq_setreleasehook(v, -1, Player_release_hook);
}
sq_remove(v, -2); // remove root table
}
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::Wind* object, bool setup_releasehook)
+void create_squirrel_instance(HSQUIRRELVM v, Scripting::ScriptedObject* object, bool setup_releasehook)
{
using namespace Wrapper;
sq_pushroottable(v);
- sq_pushstring(v, "Wind", -1);
+ sq_pushstring(v, "ScriptedObject", -1);
if(SQ_FAILED(sq_get(v, -2))) {
std::ostringstream msg;
- msg << "Couldn't resolved squirrel type 'Wind'";
+ msg << "Couldn't resolved squirrel type 'ScriptedObject'";
throw SquirrelError(v, msg.str());
}
if(SQ_FAILED(sq_createinstance(v, -1)) || SQ_FAILED(sq_setinstanceup(v, -1, object))) {
std::ostringstream msg;
- msg << "Couldn't setup squirrel instance for object of type 'Wind'";
+ msg << "Couldn't setup squirrel instance for object of type 'ScriptedObject'";
throw SquirrelError(v, msg.str());
}
sq_remove(v, -2); // remove object name
if(setup_releasehook) {
- sq_setreleasehook(v, -1, Wind_release_hook);
+ sq_setreleasehook(v, -1, ScriptedObject_release_hook);
}
sq_remove(v, -2); // remove root table
}
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::AmbientSound* object, bool setup_releasehook)
+void create_squirrel_instance(HSQUIRRELVM v, Scripting::SSector* object, bool setup_releasehook)
{
using namespace Wrapper;
sq_pushroottable(v);
- sq_pushstring(v, "AmbientSound", -1);
+ sq_pushstring(v, "SSector", -1);
if(SQ_FAILED(sq_get(v, -2))) {
std::ostringstream msg;
- msg << "Couldn't resolved squirrel type 'AmbientSound'";
+ msg << "Couldn't resolved squirrel type 'SSector'";
throw SquirrelError(v, msg.str());
}
if(SQ_FAILED(sq_createinstance(v, -1)) || SQ_FAILED(sq_setinstanceup(v, -1, object))) {
std::ostringstream msg;
- msg << "Couldn't setup squirrel instance for object of type 'AmbientSound'";
+ msg << "Couldn't setup squirrel instance for object of type 'SSector'";
throw SquirrelError(v, msg.str());
}
sq_remove(v, -2); // remove object name
if(setup_releasehook) {
- sq_setreleasehook(v, -1, AmbientSound_release_hook);
+ sq_setreleasehook(v, -1, SSector_release_hook);
}
sq_remove(v, -2); // remove root table
}
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::Thunderstorm* object, bool setup_releasehook)
+void create_squirrel_instance(HSQUIRRELVM v, Scripting::Text* object, bool setup_releasehook)
{
using namespace Wrapper;
sq_pushroottable(v);
- sq_pushstring(v, "Thunderstorm", -1);
+ sq_pushstring(v, "Text", -1);
if(SQ_FAILED(sq_get(v, -2))) {
std::ostringstream msg;
- msg << "Couldn't resolved squirrel type 'Thunderstorm'";
+ msg << "Couldn't resolved squirrel type 'Text'";
throw SquirrelError(v, msg.str());
}
if(SQ_FAILED(sq_createinstance(v, -1)) || SQ_FAILED(sq_setinstanceup(v, -1, object))) {
std::ostringstream msg;
- msg << "Couldn't setup squirrel instance for object of type 'Thunderstorm'";
+ msg << "Couldn't setup squirrel instance for object of type 'Text'";
throw SquirrelError(v, msg.str());
}
sq_remove(v, -2); // remove object name
if(setup_releasehook) {
- sq_setreleasehook(v, -1, Thunderstorm_release_hook);
+ sq_setreleasehook(v, -1, Text_release_hook);
}
sq_remove(v, -2); // remove root table
}
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::TileMap* object, bool setup_releasehook)
+void create_squirrel_instance(HSQUIRRELVM v, Scripting::Thunderstorm* object, bool setup_releasehook)
{
using namespace Wrapper;
sq_pushroottable(v);
- sq_pushstring(v, "TileMap", -1);
+ sq_pushstring(v, "Thunderstorm", -1);
if(SQ_FAILED(sq_get(v, -2))) {
std::ostringstream msg;
- msg << "Couldn't resolved squirrel type 'TileMap'";
+ msg << "Couldn't resolved squirrel type 'Thunderstorm'";
throw SquirrelError(v, msg.str());
}
if(SQ_FAILED(sq_createinstance(v, -1)) || SQ_FAILED(sq_setinstanceup(v, -1, object))) {
std::ostringstream msg;
- msg << "Couldn't setup squirrel instance for object of type 'TileMap'";
+ msg << "Couldn't setup squirrel instance for object of type 'Thunderstorm'";
throw SquirrelError(v, msg.str());
}
sq_remove(v, -2); // remove object name
if(setup_releasehook) {
- sq_setreleasehook(v, -1, TileMap_release_hook);
+ sq_setreleasehook(v, -1, Thunderstorm_release_hook);
}
sq_remove(v, -2); // remove root table
}
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::SSector* object, bool setup_releasehook)
+void create_squirrel_instance(HSQUIRRELVM v, Scripting::TileMap* object, bool setup_releasehook)
{
using namespace Wrapper;
sq_pushroottable(v);
- sq_pushstring(v, "SSector", -1);
+ sq_pushstring(v, "TileMap", -1);
if(SQ_FAILED(sq_get(v, -2))) {
std::ostringstream msg;
- msg << "Couldn't resolved squirrel type 'SSector'";
+ msg << "Couldn't resolved squirrel type 'TileMap'";
throw SquirrelError(v, msg.str());
}
if(SQ_FAILED(sq_createinstance(v, -1)) || SQ_FAILED(sq_setinstanceup(v, -1, object))) {
std::ostringstream msg;
- msg << "Couldn't setup squirrel instance for object of type 'SSector'";
+ msg << "Couldn't setup squirrel instance for object of type 'TileMap'";
throw SquirrelError(v, msg.str());
}
sq_remove(v, -2); // remove object name
if(setup_releasehook) {
- sq_setreleasehook(v, -1, SSector_release_hook);
+ sq_setreleasehook(v, -1, TileMap_release_hook);
}
sq_remove(v, -2); // remove root table
}
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::LevelTime* object, bool setup_releasehook)
+void create_squirrel_instance(HSQUIRRELVM v, Scripting::WillOWisp* object, bool setup_releasehook)
{
using namespace Wrapper;
sq_pushroottable(v);
- sq_pushstring(v, "LevelTime", -1);
+ sq_pushstring(v, "WillOWisp", -1);
if(SQ_FAILED(sq_get(v, -2))) {
std::ostringstream msg;
- msg << "Couldn't resolved squirrel type 'LevelTime'";
+ msg << "Couldn't resolved squirrel type 'WillOWisp'";
throw SquirrelError(v, msg.str());
}
if(SQ_FAILED(sq_createinstance(v, -1)) || SQ_FAILED(sq_setinstanceup(v, -1, object))) {
std::ostringstream msg;
- msg << "Couldn't setup squirrel instance for object of type 'LevelTime'";
+ msg << "Couldn't setup squirrel instance for object of type 'WillOWisp'";
throw SquirrelError(v, msg.str());
}
sq_remove(v, -2); // remove object name
if(setup_releasehook) {
- sq_setreleasehook(v, -1, LevelTime_release_hook);
+ sq_setreleasehook(v, -1, WillOWisp_release_hook);
}
sq_remove(v, -2); // remove root table
}
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::WillOWisp* object, bool setup_releasehook)
+void create_squirrel_instance(HSQUIRRELVM v, Scripting::Wind* object, bool setup_releasehook)
{
using namespace Wrapper;
sq_pushroottable(v);
- sq_pushstring(v, "WillOWisp", -1);
+ sq_pushstring(v, "Wind", -1);
if(SQ_FAILED(sq_get(v, -2))) {
std::ostringstream msg;
- msg << "Couldn't resolved squirrel type 'WillOWisp'";
+ msg << "Couldn't resolved squirrel type 'Wind'";
throw SquirrelError(v, msg.str());
}
if(SQ_FAILED(sq_createinstance(v, -1)) || SQ_FAILED(sq_setinstanceup(v, -1, object))) {
std::ostringstream msg;
- msg << "Couldn't setup squirrel instance for object of type 'WillOWisp'";
+ msg << "Couldn't setup squirrel instance for object of type 'Wind'";
throw SquirrelError(v, msg.str());
}
sq_remove(v, -2); // remove object name
if(setup_releasehook) {
- sq_setreleasehook(v, -1, WillOWisp_release_hook);
+ sq_setreleasehook(v, -1, Wind_release_hook);
}
sq_remove(v, -2); // remove root table
throw SquirrelError(v, "Couldn't register constant 'ANCHOR_BOTTOM_RIGHT'");
}
- sq_pushstring(v, "Level_finish", -1);
- sq_newclosure(v, &Level_finish_wrapper, 0);
- sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tb");
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'Level_finish'");
- }
-
- sq_pushstring(v, "Level_spawn", -1);
- sq_newclosure(v, &Level_spawn_wrapper, 0);
- sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tss");
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'Level_spawn'");
- }
-
- sq_pushstring(v, "Level_flip_vertically", -1);
- sq_newclosure(v, &Level_flip_vertically_wrapper, 0);
- sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'Level_flip_vertically'");
- }
-
- sq_pushstring(v, "Level_toggle_pause", -1);
- sq_newclosure(v, &Level_toggle_pause_wrapper, 0);
- sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'Level_toggle_pause'");
- }
-
- sq_pushstring(v, "Level_edit", -1);
- sq_newclosure(v, &Level_edit_wrapper, 0);
- sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tb");
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'Level_edit'");
- }
-
sq_pushstring(v, "display", -1);
sq_newclosure(v, &display_wrapper, 0);
sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "t.");
throw SquirrelError(v, "Couldn't register function 'play_demo'");
}
- // Register class DisplayEffect
- sq_pushstring(v, "DisplayEffect", -1);
- if(sq_newclass(v, SQFalse) < 0) {
- std::ostringstream msg;
- msg << "Couldn't create new class 'DisplayEffect'";
- throw SquirrelError(v, msg.str());
+ sq_pushstring(v, "Level_finish", -1);
+ sq_newclosure(v, &Level_finish_wrapper, 0);
+ sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tb");
+ if(SQ_FAILED(sq_createslot(v, -3))) {
+ throw SquirrelError(v, "Couldn't register function 'Level_finish'");
}
- sq_pushstring(v, "fade_out", -1);
- sq_newclosure(v, &DisplayEffect_fade_out_wrapper, 0);
- sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tn");
+
+ sq_pushstring(v, "Level_spawn", -1);
+ sq_newclosure(v, &Level_spawn_wrapper, 0);
+ sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tss");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'fade_out'");
+ throw SquirrelError(v, "Couldn't register function 'Level_spawn'");
}
- sq_pushstring(v, "fade_in", -1);
- sq_newclosure(v, &DisplayEffect_fade_in_wrapper, 0);
- sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tn");
+ sq_pushstring(v, "Level_flip_vertically", -1);
+ sq_newclosure(v, &Level_flip_vertically_wrapper, 0);
+ sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'fade_in'");
+ throw SquirrelError(v, "Couldn't register function 'Level_flip_vertically'");
}
- sq_pushstring(v, "set_black", -1);
- sq_newclosure(v, &DisplayEffect_set_black_wrapper, 0);
+ sq_pushstring(v, "Level_toggle_pause", -1);
+ sq_newclosure(v, &Level_toggle_pause_wrapper, 0);
+ sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
+ if(SQ_FAILED(sq_createslot(v, -3))) {
+ throw SquirrelError(v, "Couldn't register function 'Level_toggle_pause'");
+ }
+
+ sq_pushstring(v, "Level_edit", -1);
+ sq_newclosure(v, &Level_edit_wrapper, 0);
sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tb");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_black'");
+ throw SquirrelError(v, "Couldn't register function 'Level_edit'");
}
- sq_pushstring(v, "is_black", -1);
- sq_newclosure(v, &DisplayEffect_is_black_wrapper, 0);
- sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
+ // Register class AmbientSound
+ sq_pushstring(v, "AmbientSound", -1);
+ if(sq_newclass(v, SQFalse) < 0) {
+ std::ostringstream msg;
+ msg << "Couldn't create new class 'AmbientSound'";
+ throw SquirrelError(v, msg.str());
+ }
+ sq_pushstring(v, "set_pos", -1);
+ sq_newclosure(v, &AmbientSound_set_pos_wrapper, 0);
+ sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tnn");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'is_black'");
+ throw SquirrelError(v, "Couldn't register function 'set_pos'");
}
- sq_pushstring(v, "sixteen_to_nine", -1);
- sq_newclosure(v, &DisplayEffect_sixteen_to_nine_wrapper, 0);
- sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tn");
+ sq_pushstring(v, "get_pos_x", -1);
+ sq_newclosure(v, &AmbientSound_get_pos_x_wrapper, 0);
+ sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'sixteen_to_nine'");
+ throw SquirrelError(v, "Couldn't register function 'get_pos_x'");
}
- sq_pushstring(v, "four_to_three", -1);
- sq_newclosure(v, &DisplayEffect_four_to_three_wrapper, 0);
- sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tn");
+ sq_pushstring(v, "get_pos_y", -1);
+ sq_newclosure(v, &AmbientSound_get_pos_y_wrapper, 0);
+ sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'four_to_three'");
+ throw SquirrelError(v, "Couldn't register function 'get_pos_y'");
}
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register class 'DisplayEffect'");
+ throw SquirrelError(v, "Couldn't register class 'AmbientSound'");
}
// Register class Camera
throw SquirrelError(v, "Couldn't register class 'Camera'");
}
- // Register class ScriptedObject
- sq_pushstring(v, "ScriptedObject", -1);
+ // Register class Candle
+ sq_pushstring(v, "Candle", -1);
if(sq_newclass(v, SQFalse) < 0) {
std::ostringstream msg;
- msg << "Couldn't create new class 'ScriptedObject'";
+ msg << "Couldn't create new class 'Candle'";
throw SquirrelError(v, msg.str());
}
- sq_pushstring(v, "set_action", -1);
- sq_newclosure(v, &ScriptedObject_set_action_wrapper, 0);
- sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|ts");
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_action'");
- }
-
- sq_pushstring(v, "get_action", -1);
- sq_newclosure(v, &ScriptedObject_get_action_wrapper, 0);
+ sq_pushstring(v, "get_burning", -1);
+ sq_newclosure(v, &Candle_get_burning_wrapper, 0);
sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_action'");
+ throw SquirrelError(v, "Couldn't register function 'get_burning'");
}
- sq_pushstring(v, "move", -1);
- sq_newclosure(v, &ScriptedObject_move_wrapper, 0);
- sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tnn");
+ sq_pushstring(v, "set_burning", -1);
+ sq_newclosure(v, &Candle_set_burning_wrapper, 0);
+ sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tb");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'move'");
+ throw SquirrelError(v, "Couldn't register function 'set_burning'");
}
- sq_pushstring(v, "set_pos", -1);
- sq_newclosure(v, &ScriptedObject_set_pos_wrapper, 0);
- sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tnn");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_pos'");
+ throw SquirrelError(v, "Couldn't register class 'Candle'");
}
- sq_pushstring(v, "get_pos_x", -1);
- sq_newclosure(v, &ScriptedObject_get_pos_x_wrapper, 0);
- sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_pos_x'");
+ // Register class DisplayEffect
+ sq_pushstring(v, "DisplayEffect", -1);
+ if(sq_newclass(v, SQFalse) < 0) {
+ std::ostringstream msg;
+ msg << "Couldn't create new class 'DisplayEffect'";
+ throw SquirrelError(v, msg.str());
}
-
- sq_pushstring(v, "get_pos_y", -1);
- sq_newclosure(v, &ScriptedObject_get_pos_y_wrapper, 0);
- sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
+ sq_pushstring(v, "fade_out", -1);
+ sq_newclosure(v, &DisplayEffect_fade_out_wrapper, 0);
+ sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tn");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_pos_y'");
+ throw SquirrelError(v, "Couldn't register function 'fade_out'");
}
- sq_pushstring(v, "set_velocity", -1);
- sq_newclosure(v, &ScriptedObject_set_velocity_wrapper, 0);
- sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tnn");
+ sq_pushstring(v, "fade_in", -1);
+ sq_newclosure(v, &DisplayEffect_fade_in_wrapper, 0);
+ sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tn");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_velocity'");
+ throw SquirrelError(v, "Couldn't register function 'fade_in'");
}
- sq_pushstring(v, "get_velocity_x", -1);
- sq_newclosure(v, &ScriptedObject_get_velocity_x_wrapper, 0);
- sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
+ sq_pushstring(v, "set_black", -1);
+ sq_newclosure(v, &DisplayEffect_set_black_wrapper, 0);
+ sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tb");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_velocity_x'");
+ throw SquirrelError(v, "Couldn't register function 'set_black'");
}
- sq_pushstring(v, "get_velocity_y", -1);
- sq_newclosure(v, &ScriptedObject_get_velocity_y_wrapper, 0);
+ sq_pushstring(v, "is_black", -1);
+ sq_newclosure(v, &DisplayEffect_is_black_wrapper, 0);
sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_velocity_y'");
+ throw SquirrelError(v, "Couldn't register function 'is_black'");
}
- sq_pushstring(v, "set_visible", -1);
- sq_newclosure(v, &ScriptedObject_set_visible_wrapper, 0);
- sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tb");
+ sq_pushstring(v, "sixteen_to_nine", -1);
+ sq_newclosure(v, &DisplayEffect_sixteen_to_nine_wrapper, 0);
+ sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tn");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_visible'");
+ throw SquirrelError(v, "Couldn't register function 'sixteen_to_nine'");
}
- sq_pushstring(v, "is_visible", -1);
- sq_newclosure(v, &ScriptedObject_is_visible_wrapper, 0);
+ sq_pushstring(v, "four_to_three", -1);
+ sq_newclosure(v, &DisplayEffect_four_to_three_wrapper, 0);
+ sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tn");
+ if(SQ_FAILED(sq_createslot(v, -3))) {
+ throw SquirrelError(v, "Couldn't register function 'four_to_three'");
+ }
+
+ if(SQ_FAILED(sq_createslot(v, -3))) {
+ throw SquirrelError(v, "Couldn't register class 'DisplayEffect'");
+ }
+
+ // Register class FloatingImage
+ sq_pushstring(v, "FloatingImage", -1);
+ if(sq_newclass(v, SQFalse) < 0) {
+ std::ostringstream msg;
+ msg << "Couldn't create new class 'FloatingImage'";
+ throw SquirrelError(v, msg.str());
+ }
+ sq_pushstring(v, "constructor", -1);
+ sq_newclosure(v, &FloatingImage_constructor_wrapper, 0);
+ sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|ts");
+ if(SQ_FAILED(sq_createslot(v, -3))) {
+ throw SquirrelError(v, "Couldn't register function 'constructor'");
+ }
+
+ sq_pushstring(v, "set_layer", -1);
+ sq_newclosure(v, &FloatingImage_set_layer_wrapper, 0);
+ sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|ti");
+ if(SQ_FAILED(sq_createslot(v, -3))) {
+ throw SquirrelError(v, "Couldn't register function 'set_layer'");
+ }
+
+ sq_pushstring(v, "get_layer", -1);
+ sq_newclosure(v, &FloatingImage_get_layer_wrapper, 0);
sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'is_visible'");
+ throw SquirrelError(v, "Couldn't register function 'get_layer'");
}
- sq_pushstring(v, "set_solid", -1);
- sq_newclosure(v, &ScriptedObject_set_solid_wrapper, 0);
- sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tb");
+ sq_pushstring(v, "set_pos", -1);
+ sq_newclosure(v, &FloatingImage_set_pos_wrapper, 0);
+ sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tnn");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_solid'");
+ throw SquirrelError(v, "Couldn't register function 'set_pos'");
}
- sq_pushstring(v, "is_solid", -1);
- sq_newclosure(v, &ScriptedObject_is_solid_wrapper, 0);
+ sq_pushstring(v, "get_pos_x", -1);
+ sq_newclosure(v, &FloatingImage_get_pos_x_wrapper, 0);
sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'is_solid'");
+ throw SquirrelError(v, "Couldn't register function 'get_pos_x'");
}
- sq_pushstring(v, "get_name", -1);
- sq_newclosure(v, &ScriptedObject_get_name_wrapper, 0);
+ sq_pushstring(v, "get_pos_y", -1);
+ sq_newclosure(v, &FloatingImage_get_pos_y_wrapper, 0);
sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_name'");
+ throw SquirrelError(v, "Couldn't register function 'get_pos_y'");
}
+ sq_pushstring(v, "set_anchor_point", -1);
+ sq_newclosure(v, &FloatingImage_set_anchor_point_wrapper, 0);
+ sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|ti");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register class 'ScriptedObject'");
+ throw SquirrelError(v, "Couldn't register function 'set_anchor_point'");
}
- // Register class Text
- sq_pushstring(v, "Text", -1);
- if(sq_newclass(v, SQFalse) < 0) {
- std::ostringstream msg;
- msg << "Couldn't create new class 'Text'";
- throw SquirrelError(v, msg.str());
+ sq_pushstring(v, "get_anchor_point", -1);
+ sq_newclosure(v, &FloatingImage_get_anchor_point_wrapper, 0);
+ sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
+ if(SQ_FAILED(sq_createslot(v, -3))) {
+ throw SquirrelError(v, "Couldn't register function 'get_anchor_point'");
}
- sq_pushstring(v, "set_text", -1);
- sq_newclosure(v, &Text_set_text_wrapper, 0);
- sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|ts");
+
+ sq_pushstring(v, "set_visible", -1);
+ sq_newclosure(v, &FloatingImage_set_visible_wrapper, 0);
+ sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tb");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_text'");
+ throw SquirrelError(v, "Couldn't register function 'set_visible'");
}
- sq_pushstring(v, "set_font", -1);
- sq_newclosure(v, &Text_set_font_wrapper, 0);
+ sq_pushstring(v, "get_visible", -1);
+ sq_newclosure(v, &FloatingImage_get_visible_wrapper, 0);
+ sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
+ if(SQ_FAILED(sq_createslot(v, -3))) {
+ throw SquirrelError(v, "Couldn't register function 'get_visible'");
+ }
+
+ sq_pushstring(v, "set_action", -1);
+ sq_newclosure(v, &FloatingImage_set_action_wrapper, 0);
sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|ts");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_font'");
+ throw SquirrelError(v, "Couldn't register function 'set_action'");
+ }
+
+ sq_pushstring(v, "get_action", -1);
+ sq_newclosure(v, &FloatingImage_get_action_wrapper, 0);
+ sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
+ if(SQ_FAILED(sq_createslot(v, -3))) {
+ throw SquirrelError(v, "Couldn't register function 'get_action'");
}
sq_pushstring(v, "fade_in", -1);
- sq_newclosure(v, &Text_fade_in_wrapper, 0);
+ sq_newclosure(v, &FloatingImage_fade_in_wrapper, 0);
sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tn");
if(SQ_FAILED(sq_createslot(v, -3))) {
throw SquirrelError(v, "Couldn't register function 'fade_in'");
}
sq_pushstring(v, "fade_out", -1);
- sq_newclosure(v, &Text_fade_out_wrapper, 0);
+ sq_newclosure(v, &FloatingImage_fade_out_wrapper, 0);
sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tn");
if(SQ_FAILED(sq_createslot(v, -3))) {
throw SquirrelError(v, "Couldn't register function 'fade_out'");
}
- sq_pushstring(v, "set_visible", -1);
- sq_newclosure(v, &Text_set_visible_wrapper, 0);
- sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tb");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_visible'");
+ throw SquirrelError(v, "Couldn't register class 'FloatingImage'");
}
- sq_pushstring(v, "set_centered", -1);
- sq_newclosure(v, &Text_set_centered_wrapper, 0);
- sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tb");
+ // Register class LevelTime
+ sq_pushstring(v, "LevelTime", -1);
+ if(sq_newclass(v, SQFalse) < 0) {
+ std::ostringstream msg;
+ msg << "Couldn't create new class 'LevelTime'";
+ throw SquirrelError(v, msg.str());
+ }
+ sq_pushstring(v, "start", -1);
+ sq_newclosure(v, &LevelTime_start_wrapper, 0);
+ sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_centered'");
+ throw SquirrelError(v, "Couldn't register function 'start'");
}
- sq_pushstring(v, "set_pos", -1);
- sq_newclosure(v, &Text_set_pos_wrapper, 0);
- sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tnn");
+ sq_pushstring(v, "stop", -1);
+ sq_newclosure(v, &LevelTime_stop_wrapper, 0);
+ sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_pos'");
+ throw SquirrelError(v, "Couldn't register function 'stop'");
}
- sq_pushstring(v, "get_pos_x", -1);
- sq_newclosure(v, &Text_get_pos_x_wrapper, 0);
+ sq_pushstring(v, "get_time", -1);
+ sq_newclosure(v, &LevelTime_get_time_wrapper, 0);
sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_pos_x'");
+ throw SquirrelError(v, "Couldn't register function 'get_time'");
}
- sq_pushstring(v, "get_pos_y", -1);
- sq_newclosure(v, &Text_get_pos_y_wrapper, 0);
- sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
+ sq_pushstring(v, "set_time", -1);
+ sq_newclosure(v, &LevelTime_set_time_wrapper, 0);
+ sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tn");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_pos_y'");
+ throw SquirrelError(v, "Couldn't register function 'set_time'");
}
- sq_pushstring(v, "set_anchor_point", -1);
- sq_newclosure(v, &Text_set_anchor_point_wrapper, 0);
+ if(SQ_FAILED(sq_createslot(v, -3))) {
+ throw SquirrelError(v, "Couldn't register class 'LevelTime'");
+ }
+
+ // Register class Platform
+ sq_pushstring(v, "Platform", -1);
+ if(sq_newclass(v, SQFalse) < 0) {
+ std::ostringstream msg;
+ msg << "Couldn't create new class 'Platform'";
+ throw SquirrelError(v, msg.str());
+ }
+ sq_pushstring(v, "goto_node", -1);
+ sq_newclosure(v, &Platform_goto_node_wrapper, 0);
sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|ti");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_anchor_point'");
+ throw SquirrelError(v, "Couldn't register function 'goto_node'");
}
- sq_pushstring(v, "get_anchor_point", -1);
- sq_newclosure(v, &Text_get_anchor_point_wrapper, 0);
+ sq_pushstring(v, "start_moving", -1);
+ sq_newclosure(v, &Platform_start_moving_wrapper, 0);
sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_anchor_point'");
+ throw SquirrelError(v, "Couldn't register function 'start_moving'");
}
+ sq_pushstring(v, "stop_moving", -1);
+ sq_newclosure(v, &Platform_stop_moving_wrapper, 0);
+ sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register class 'Text'");
+ throw SquirrelError(v, "Couldn't register function 'stop_moving'");
+ }
+
+ if(SQ_FAILED(sq_createslot(v, -3))) {
+ throw SquirrelError(v, "Couldn't register class 'Platform'");
}
// Register class Player
throw SquirrelError(v, "Couldn't register class 'Player'");
}
- // Register class FloatingImage
- sq_pushstring(v, "FloatingImage", -1);
+ // Register class ScriptedObject
+ sq_pushstring(v, "ScriptedObject", -1);
if(sq_newclass(v, SQFalse) < 0) {
std::ostringstream msg;
- msg << "Couldn't create new class 'FloatingImage'";
+ msg << "Couldn't create new class 'ScriptedObject'";
throw SquirrelError(v, msg.str());
}
- sq_pushstring(v, "constructor", -1);
- sq_newclosure(v, &FloatingImage_constructor_wrapper, 0);
+ sq_pushstring(v, "set_action", -1);
+ sq_newclosure(v, &ScriptedObject_set_action_wrapper, 0);
sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|ts");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'constructor'");
+ throw SquirrelError(v, "Couldn't register function 'set_action'");
}
- sq_pushstring(v, "set_layer", -1);
- sq_newclosure(v, &FloatingImage_set_layer_wrapper, 0);
- sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|ti");
+ sq_pushstring(v, "get_action", -1);
+ sq_newclosure(v, &ScriptedObject_get_action_wrapper, 0);
+ sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_layer'");
+ throw SquirrelError(v, "Couldn't register function 'get_action'");
}
- sq_pushstring(v, "get_layer", -1);
- sq_newclosure(v, &FloatingImage_get_layer_wrapper, 0);
- sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
+ sq_pushstring(v, "move", -1);
+ sq_newclosure(v, &ScriptedObject_move_wrapper, 0);
+ sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tnn");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_layer'");
+ throw SquirrelError(v, "Couldn't register function 'move'");
}
sq_pushstring(v, "set_pos", -1);
- sq_newclosure(v, &FloatingImage_set_pos_wrapper, 0);
+ sq_newclosure(v, &ScriptedObject_set_pos_wrapper, 0);
sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tnn");
if(SQ_FAILED(sq_createslot(v, -3))) {
throw SquirrelError(v, "Couldn't register function 'set_pos'");
}
sq_pushstring(v, "get_pos_x", -1);
- sq_newclosure(v, &FloatingImage_get_pos_x_wrapper, 0);
+ sq_newclosure(v, &ScriptedObject_get_pos_x_wrapper, 0);
sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
if(SQ_FAILED(sq_createslot(v, -3))) {
throw SquirrelError(v, "Couldn't register function 'get_pos_x'");
}
sq_pushstring(v, "get_pos_y", -1);
- sq_newclosure(v, &FloatingImage_get_pos_y_wrapper, 0);
+ sq_newclosure(v, &ScriptedObject_get_pos_y_wrapper, 0);
sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
if(SQ_FAILED(sq_createslot(v, -3))) {
throw SquirrelError(v, "Couldn't register function 'get_pos_y'");
}
- sq_pushstring(v, "set_anchor_point", -1);
- sq_newclosure(v, &FloatingImage_set_anchor_point_wrapper, 0);
- sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|ti");
+ sq_pushstring(v, "set_velocity", -1);
+ sq_newclosure(v, &ScriptedObject_set_velocity_wrapper, 0);
+ sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tnn");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_anchor_point'");
+ throw SquirrelError(v, "Couldn't register function 'set_velocity'");
}
- sq_pushstring(v, "get_anchor_point", -1);
- sq_newclosure(v, &FloatingImage_get_anchor_point_wrapper, 0);
+ sq_pushstring(v, "get_velocity_x", -1);
+ sq_newclosure(v, &ScriptedObject_get_velocity_x_wrapper, 0);
sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_anchor_point'");
+ throw SquirrelError(v, "Couldn't register function 'get_velocity_x'");
+ }
+
+ sq_pushstring(v, "get_velocity_y", -1);
+ sq_newclosure(v, &ScriptedObject_get_velocity_y_wrapper, 0);
+ sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
+ if(SQ_FAILED(sq_createslot(v, -3))) {
+ throw SquirrelError(v, "Couldn't register function 'get_velocity_y'");
}
sq_pushstring(v, "set_visible", -1);
- sq_newclosure(v, &FloatingImage_set_visible_wrapper, 0);
+ sq_newclosure(v, &ScriptedObject_set_visible_wrapper, 0);
sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tb");
if(SQ_FAILED(sq_createslot(v, -3))) {
throw SquirrelError(v, "Couldn't register function 'set_visible'");
}
- sq_pushstring(v, "get_visible", -1);
- sq_newclosure(v, &FloatingImage_get_visible_wrapper, 0);
+ sq_pushstring(v, "is_visible", -1);
+ sq_newclosure(v, &ScriptedObject_is_visible_wrapper, 0);
sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_visible'");
+ throw SquirrelError(v, "Couldn't register function 'is_visible'");
}
- sq_pushstring(v, "set_action", -1);
- sq_newclosure(v, &FloatingImage_set_action_wrapper, 0);
- sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|ts");
+ sq_pushstring(v, "set_solid", -1);
+ sq_newclosure(v, &ScriptedObject_set_solid_wrapper, 0);
+ sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tb");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_action'");
+ throw SquirrelError(v, "Couldn't register function 'set_solid'");
}
- sq_pushstring(v, "get_action", -1);
- sq_newclosure(v, &FloatingImage_get_action_wrapper, 0);
+ sq_pushstring(v, "is_solid", -1);
+ sq_newclosure(v, &ScriptedObject_is_solid_wrapper, 0);
sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_action'");
- }
-
- sq_pushstring(v, "fade_in", -1);
- sq_newclosure(v, &FloatingImage_fade_in_wrapper, 0);
- sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tn");
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'fade_in'");
+ throw SquirrelError(v, "Couldn't register function 'is_solid'");
}
- sq_pushstring(v, "fade_out", -1);
- sq_newclosure(v, &FloatingImage_fade_out_wrapper, 0);
- sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tn");
+ sq_pushstring(v, "get_name", -1);
+ sq_newclosure(v, &ScriptedObject_get_name_wrapper, 0);
+ sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'fade_out'");
+ throw SquirrelError(v, "Couldn't register function 'get_name'");
}
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register class 'FloatingImage'");
+ throw SquirrelError(v, "Couldn't register class 'ScriptedObject'");
}
- // Register class Platform
- sq_pushstring(v, "Platform", -1);
+ // Register class SSector
+ sq_pushstring(v, "SSector", -1);
if(sq_newclass(v, SQFalse) < 0) {
std::ostringstream msg;
- msg << "Couldn't create new class 'Platform'";
+ msg << "Couldn't create new class 'SSector'";
throw SquirrelError(v, msg.str());
}
- sq_pushstring(v, "goto_node", -1);
- sq_newclosure(v, &Platform_goto_node_wrapper, 0);
- sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|ti");
+ sq_pushstring(v, "set_ambient_light", -1);
+ sq_newclosure(v, &SSector_set_ambient_light_wrapper, 0);
+ sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tnnn");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'goto_node'");
+ throw SquirrelError(v, "Couldn't register function 'set_ambient_light'");
}
- sq_pushstring(v, "start_moving", -1);
- sq_newclosure(v, &Platform_start_moving_wrapper, 0);
+ sq_pushstring(v, "get_ambient_red", -1);
+ sq_newclosure(v, &SSector_get_ambient_red_wrapper, 0);
sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'start_moving'");
+ throw SquirrelError(v, "Couldn't register function 'get_ambient_red'");
}
- sq_pushstring(v, "stop_moving", -1);
- sq_newclosure(v, &Platform_stop_moving_wrapper, 0);
+ sq_pushstring(v, "get_ambient_green", -1);
+ sq_newclosure(v, &SSector_get_ambient_green_wrapper, 0);
sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'stop_moving'");
+ throw SquirrelError(v, "Couldn't register function 'get_ambient_green'");
+ }
+
+ sq_pushstring(v, "get_ambient_blue", -1);
+ sq_newclosure(v, &SSector_get_ambient_blue_wrapper, 0);
+ sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
+ if(SQ_FAILED(sq_createslot(v, -3))) {
+ throw SquirrelError(v, "Couldn't register function 'get_ambient_blue'");
+ }
+
+ sq_pushstring(v, "set_gravity", -1);
+ sq_newclosure(v, &SSector_set_gravity_wrapper, 0);
+ sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tn");
+ if(SQ_FAILED(sq_createslot(v, -3))) {
+ throw SquirrelError(v, "Couldn't register function 'set_gravity'");
}
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register class 'Platform'");
+ throw SquirrelError(v, "Couldn't register class 'SSector'");
}
- // Register class Candle
- sq_pushstring(v, "Candle", -1);
+ // Register class Text
+ sq_pushstring(v, "Text", -1);
if(sq_newclass(v, SQFalse) < 0) {
std::ostringstream msg;
- msg << "Couldn't create new class 'Candle'";
+ msg << "Couldn't create new class 'Text'";
throw SquirrelError(v, msg.str());
}
- sq_pushstring(v, "get_burning", -1);
- sq_newclosure(v, &Candle_get_burning_wrapper, 0);
- sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
+ sq_pushstring(v, "set_text", -1);
+ sq_newclosure(v, &Text_set_text_wrapper, 0);
+ sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|ts");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_burning'");
+ throw SquirrelError(v, "Couldn't register function 'set_text'");
}
- sq_pushstring(v, "set_burning", -1);
- sq_newclosure(v, &Candle_set_burning_wrapper, 0);
- sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tb");
+ sq_pushstring(v, "set_font", -1);
+ sq_newclosure(v, &Text_set_font_wrapper, 0);
+ sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|ts");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_burning'");
+ throw SquirrelError(v, "Couldn't register function 'set_font'");
}
+ sq_pushstring(v, "fade_in", -1);
+ sq_newclosure(v, &Text_fade_in_wrapper, 0);
+ sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tn");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register class 'Candle'");
+ throw SquirrelError(v, "Couldn't register function 'fade_in'");
}
- // Register class Wind
- sq_pushstring(v, "Wind", -1);
- if(sq_newclass(v, SQFalse) < 0) {
- std::ostringstream msg;
- msg << "Couldn't create new class 'Wind'";
- throw SquirrelError(v, msg.str());
- }
- sq_pushstring(v, "start", -1);
- sq_newclosure(v, &Wind_start_wrapper, 0);
- sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
+ sq_pushstring(v, "fade_out", -1);
+ sq_newclosure(v, &Text_fade_out_wrapper, 0);
+ sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tn");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'start'");
+ throw SquirrelError(v, "Couldn't register function 'fade_out'");
}
- sq_pushstring(v, "stop", -1);
- sq_newclosure(v, &Wind_stop_wrapper, 0);
- sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
+ sq_pushstring(v, "set_visible", -1);
+ sq_newclosure(v, &Text_set_visible_wrapper, 0);
+ sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tb");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'stop'");
+ throw SquirrelError(v, "Couldn't register function 'set_visible'");
}
+ sq_pushstring(v, "set_centered", -1);
+ sq_newclosure(v, &Text_set_centered_wrapper, 0);
+ sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tb");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register class 'Wind'");
+ throw SquirrelError(v, "Couldn't register function 'set_centered'");
}
- // Register class AmbientSound
- sq_pushstring(v, "AmbientSound", -1);
- if(sq_newclass(v, SQFalse) < 0) {
- std::ostringstream msg;
- msg << "Couldn't create new class 'AmbientSound'";
- throw SquirrelError(v, msg.str());
- }
sq_pushstring(v, "set_pos", -1);
- sq_newclosure(v, &AmbientSound_set_pos_wrapper, 0);
+ sq_newclosure(v, &Text_set_pos_wrapper, 0);
sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tnn");
if(SQ_FAILED(sq_createslot(v, -3))) {
throw SquirrelError(v, "Couldn't register function 'set_pos'");
}
sq_pushstring(v, "get_pos_x", -1);
- sq_newclosure(v, &AmbientSound_get_pos_x_wrapper, 0);
+ sq_newclosure(v, &Text_get_pos_x_wrapper, 0);
sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
if(SQ_FAILED(sq_createslot(v, -3))) {
throw SquirrelError(v, "Couldn't register function 'get_pos_x'");
}
sq_pushstring(v, "get_pos_y", -1);
- sq_newclosure(v, &AmbientSound_get_pos_y_wrapper, 0);
+ sq_newclosure(v, &Text_get_pos_y_wrapper, 0);
sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
if(SQ_FAILED(sq_createslot(v, -3))) {
throw SquirrelError(v, "Couldn't register function 'get_pos_y'");
}
+ sq_pushstring(v, "set_anchor_point", -1);
+ sq_newclosure(v, &Text_set_anchor_point_wrapper, 0);
+ sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|ti");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register class 'AmbientSound'");
+ throw SquirrelError(v, "Couldn't register function 'set_anchor_point'");
+ }
+
+ sq_pushstring(v, "get_anchor_point", -1);
+ sq_newclosure(v, &Text_get_anchor_point_wrapper, 0);
+ sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
+ if(SQ_FAILED(sq_createslot(v, -3))) {
+ throw SquirrelError(v, "Couldn't register function 'get_anchor_point'");
+ }
+
+ if(SQ_FAILED(sq_createslot(v, -3))) {
+ throw SquirrelError(v, "Couldn't register class 'Text'");
}
// Register class Thunderstorm
throw SquirrelError(v, "Couldn't register class 'TileMap'");
}
- // Register class SSector
- sq_pushstring(v, "SSector", -1);
+ // Register class WillOWisp
+ sq_pushstring(v, "WillOWisp", -1);
if(sq_newclass(v, SQFalse) < 0) {
std::ostringstream msg;
- msg << "Couldn't create new class 'SSector'";
+ msg << "Couldn't create new class 'WillOWisp'";
throw SquirrelError(v, msg.str());
}
- sq_pushstring(v, "set_ambient_light", -1);
- sq_newclosure(v, &SSector_set_ambient_light_wrapper, 0);
- sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tnnn");
+ sq_pushstring(v, "goto_node", -1);
+ sq_newclosure(v, &WillOWisp_goto_node_wrapper, 0);
+ sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|ti");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_ambient_light'");
+ throw SquirrelError(v, "Couldn't register function 'goto_node'");
}
- sq_pushstring(v, "get_ambient_red", -1);
- sq_newclosure(v, &SSector_get_ambient_red_wrapper, 0);
- sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
+ sq_pushstring(v, "set_state", -1);
+ sq_newclosure(v, &WillOWisp_set_state_wrapper, 0);
+ sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|ts");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_ambient_red'");
+ throw SquirrelError(v, "Couldn't register function 'set_state'");
}
- sq_pushstring(v, "get_ambient_green", -1);
- sq_newclosure(v, &SSector_get_ambient_green_wrapper, 0);
+ sq_pushstring(v, "start_moving", -1);
+ sq_newclosure(v, &WillOWisp_start_moving_wrapper, 0);
sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_ambient_green'");
+ throw SquirrelError(v, "Couldn't register function 'start_moving'");
}
- sq_pushstring(v, "get_ambient_blue", -1);
- sq_newclosure(v, &SSector_get_ambient_blue_wrapper, 0);
+ sq_pushstring(v, "stop_moving", -1);
+ sq_newclosure(v, &WillOWisp_stop_moving_wrapper, 0);
sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_ambient_blue'");
- }
-
- sq_pushstring(v, "set_gravity", -1);
- sq_newclosure(v, &SSector_set_gravity_wrapper, 0);
- sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tn");
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_gravity'");
+ throw SquirrelError(v, "Couldn't register function 'stop_moving'");
}
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register class 'SSector'");
+ throw SquirrelError(v, "Couldn't register class 'WillOWisp'");
}
- // Register class LevelTime
- sq_pushstring(v, "LevelTime", -1);
+ // Register class Wind
+ sq_pushstring(v, "Wind", -1);
if(sq_newclass(v, SQFalse) < 0) {
std::ostringstream msg;
- msg << "Couldn't create new class 'LevelTime'";
+ msg << "Couldn't create new class 'Wind'";
throw SquirrelError(v, msg.str());
}
sq_pushstring(v, "start", -1);
- sq_newclosure(v, &LevelTime_start_wrapper, 0);
+ sq_newclosure(v, &Wind_start_wrapper, 0);
sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
if(SQ_FAILED(sq_createslot(v, -3))) {
throw SquirrelError(v, "Couldn't register function 'start'");
}
sq_pushstring(v, "stop", -1);
- sq_newclosure(v, &LevelTime_stop_wrapper, 0);
+ sq_newclosure(v, &Wind_stop_wrapper, 0);
sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
if(SQ_FAILED(sq_createslot(v, -3))) {
throw SquirrelError(v, "Couldn't register function 'stop'");
}
- sq_pushstring(v, "get_time", -1);
- sq_newclosure(v, &LevelTime_get_time_wrapper, 0);
- sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'get_time'");
- }
-
- sq_pushstring(v, "set_time", -1);
- sq_newclosure(v, &LevelTime_set_time_wrapper, 0);
- sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|tn");
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_time'");
- }
-
if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register class 'LevelTime'");
- }
-
- // Register class WillOWisp
- sq_pushstring(v, "WillOWisp", -1);
- if(sq_newclass(v, SQFalse) < 0) {
- std::ostringstream msg;
- msg << "Couldn't create new class 'WillOWisp'";
- throw SquirrelError(v, msg.str());
- }
- sq_pushstring(v, "goto_node", -1);
- sq_newclosure(v, &WillOWisp_goto_node_wrapper, 0);
- sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|ti");
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'goto_node'");
- }
-
- sq_pushstring(v, "set_state", -1);
- sq_newclosure(v, &WillOWisp_set_state_wrapper, 0);
- sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|ts");
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'set_state'");
- }
-
- sq_pushstring(v, "start_moving", -1);
- sq_newclosure(v, &WillOWisp_start_moving_wrapper, 0);
- sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'start_moving'");
- }
-
- sq_pushstring(v, "stop_moving", -1);
- sq_newclosure(v, &WillOWisp_stop_moving_wrapper, 0);
- sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register function 'stop_moving'");
- }
-
- if(SQ_FAILED(sq_createslot(v, -3))) {
- throw SquirrelError(v, "Couldn't register class 'WillOWisp'");
+ throw SquirrelError(v, "Couldn't register class 'Wind'");
}
}
} // end of namespace Scripting
+
+/* EOF */
* 'src/scripting/wrapper.interface.hpp'
* DO NOT CHANGE
*/
-#ifndef __supertux_WRAPPER_H__
-#define __supertux_WRAPPER_H__
+#ifndef HEADER_SUPERTUX_SCRIPTING_WRAPPER_HPP
+#define HEADER_SUPERTUX_SCRIPTING_WRAPPER_HPP
-#include <squirrel.h>
-
-namespace Scripting
-{
+namespace Scripting {
void register_supertux_wrapper(HSQUIRRELVM v);
-class DisplayEffect;
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::DisplayEffect* object, bool setup_releasehook = false);
+class AmbientSound;
+void create_squirrel_instance(HSQUIRRELVM v, Scripting::AmbientSound* object, bool setup_releasehook = false);
class Camera;
void create_squirrel_instance(HSQUIRRELVM v, Scripting::Camera* object, bool setup_releasehook = false);
-class ScriptedObject;
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::ScriptedObject* object, bool setup_releasehook = false);
-class Text;
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::Text* object, bool setup_releasehook = false);
-class Player;
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::Player* object, bool setup_releasehook = false);
+class Candle;
+void create_squirrel_instance(HSQUIRRELVM v, Scripting::Candle* object, bool setup_releasehook = false);
+class DisplayEffect;
+void create_squirrel_instance(HSQUIRRELVM v, Scripting::DisplayEffect* object, bool setup_releasehook = false);
class FloatingImage;
void create_squirrel_instance(HSQUIRRELVM v, Scripting::FloatingImage* object, bool setup_releasehook = false);
+class LevelTime;
+void create_squirrel_instance(HSQUIRRELVM v, Scripting::LevelTime* object, bool setup_releasehook = false);
class Platform;
void create_squirrel_instance(HSQUIRRELVM v, Scripting::Platform* object, bool setup_releasehook = false);
-class Candle;
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::Candle* object, bool setup_releasehook = false);
-class Wind;
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::Wind* object, bool setup_releasehook = false);
-class AmbientSound;
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::AmbientSound* object, bool setup_releasehook = false);
+class Player;
+void create_squirrel_instance(HSQUIRRELVM v, Scripting::Player* object, bool setup_releasehook = false);
+class ScriptedObject;
+void create_squirrel_instance(HSQUIRRELVM v, Scripting::ScriptedObject* object, bool setup_releasehook = false);
+class SSector;
+void create_squirrel_instance(HSQUIRRELVM v, Scripting::SSector* object, bool setup_releasehook = false);
+class Text;
+void create_squirrel_instance(HSQUIRRELVM v, Scripting::Text* object, bool setup_releasehook = false);
class Thunderstorm;
void create_squirrel_instance(HSQUIRRELVM v, Scripting::Thunderstorm* object, bool setup_releasehook = false);
class TileMap;
void create_squirrel_instance(HSQUIRRELVM v, Scripting::TileMap* object, bool setup_releasehook = false);
-class SSector;
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::SSector* object, bool setup_releasehook = false);
-class LevelTime;
-void create_squirrel_instance(HSQUIRRELVM v, Scripting::LevelTime* object, bool setup_releasehook = false);
class WillOWisp;
void create_squirrel_instance(HSQUIRRELVM v, Scripting::WillOWisp* object, bool setup_releasehook = false);
+class Wind;
+void create_squirrel_instance(HSQUIRRELVM v, Scripting::Wind* object, bool setup_releasehook = false);
}
#endif
+
+/* EOF */
/* This file is processed by miniswig to produce the scripting API */
-#include "display_effect.hpp"
-#include "camera.hpp"
-#include "level.hpp"
-#include "scripted_object.hpp"
-#include "text.hpp"
-#include "functions.hpp"
-#include "player.hpp"
-#include "floating_image.hpp"
-#include "anchor_points.hpp"
-#include "platform.hpp"
-#include "candle.hpp"
-#include "wind.hpp"
-#include "ambient_sound.hpp"
-#include "thunderstorm.hpp"
-#include "tilemap.hpp"
-#include "ssector.hpp"
-#include "level_time.hpp"
-#include "willowisp.hpp"
+#include "scripting/ambient_sound.hpp"
+#include "scripting/anchor_points.hpp"
+#include "scripting/camera.hpp"
+#include "scripting/candle.hpp"
+#include "scripting/display_effect.hpp"
+#include "scripting/floating_image.hpp"
+#include "scripting/functions.hpp"
+#include "scripting/level.hpp"
+#include "scripting/level_time.hpp"
+#include "scripting/platform.hpp"
+#include "scripting/player.hpp"
+#include "scripting/scripted_object.hpp"
+#include "scripting/ssector.hpp"
+#include "scripting/text.hpp"
+#include "scripting/thunderstorm.hpp"
+#include "scripting/tilemap.hpp"
+#include "scripting/willowisp.hpp"
+#include "scripting/wind.hpp"
+
+/* EOF */
+++ /dev/null
-// $Id$
-//
-// SuperTux - A Jump'n Run
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include <config.h>
-
-#include <memory>
-#include <algorithm>
-#include <stdexcept>
-#include <iostream>
-#include <fstream>
-#include <sstream>
-#include <stdexcept>
-#include <float.h>
-#include <math.h>
-#include <limits>
-#include <physfs.h>
-
-#include "sector.hpp"
-#include "object/player.hpp"
-#include "object/gameobjs.hpp"
-#include "object/camera.hpp"
-#include "object/background.hpp"
-#include "object/gradient.hpp"
-#include "object/particlesystem.hpp"
-#include "object/particlesystem_interactive.hpp"
-#include "object/tilemap.hpp"
-#include "lisp/parser.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-#include "lisp/list_iterator.hpp"
-#include "tile.hpp"
-#include "file_system.hpp"
-#include "physfs/physfs_stream.hpp"
-#include "audio/sound_manager.hpp"
-#include "game_session.hpp"
-#include "constants.hpp"
-#include "resources.hpp"
-#include "statistics.hpp"
-#include "object_factory.hpp"
-#include "collision.hpp"
-#include "spawn_point.hpp"
-#include "math/rect.hpp"
-#include "math/aatriangle.hpp"
-#include "object/coin.hpp"
-#include "object/block.hpp"
-#include "object/invisible_block.hpp"
-#include "object/light.hpp"
-#include "object/pulsing_light.hpp"
-#include "object/bullet.hpp"
-#include "object/text_object.hpp"
-#include "object/portable.hpp"
-#include "object/display_effect.hpp"
-#include "badguy/jumpy.hpp"
-#include "trigger/sequence_trigger.hpp"
-#include "player_status.hpp"
-#include "scripting/squirrel_util.hpp"
-#include "script_interface.hpp"
-#include "log.hpp"
-#include "main.hpp"
-#include "level.hpp"
-
-Sector* Sector::_current = 0;
-
-bool Sector::show_collrects = false;
-bool Sector::draw_solids_only = false;
-
-Sector::Sector(Level* parent)
- : level(parent), currentmusic(LEVEL_MUSIC),
- ambient_light( 1.0f, 1.0f, 1.0f, 1.0f ), gravity(10.0), player(0), camera(0), effect(0)
-{
- add_object(new Player(player_status, "Tux"));
- add_object(new DisplayEffect("Effect"));
- add_object(new TextObject("Text"));
-
- sound_manager->preload("sounds/shoot.wav");
-
- // create a new squirrel table for the sector
- using namespace Scripting;
-
- sq_collectgarbage(global_vm);
-
- sq_newtable(global_vm);
- sq_pushroottable(global_vm);
- if(SQ_FAILED(sq_setdelegate(global_vm, -2)))
- throw Scripting::SquirrelError(global_vm, "Couldn't set sector_table delegate");
-
- sq_resetobject(§or_table);
- if(SQ_FAILED(sq_getstackobj(global_vm, -1, §or_table)))
- throw Scripting::SquirrelError(global_vm, "Couldn't get sector table");
- sq_addref(global_vm, §or_table);
- sq_pop(global_vm, 1);
-}
-
-Sector::~Sector()
-{
- using namespace Scripting;
-
- deactivate();
-
- for(ScriptList::iterator i = scripts.begin();
- i != scripts.end(); ++i) {
- HSQOBJECT& object = *i;
- sq_release(global_vm, &object);
- }
- sq_release(global_vm, §or_table);
- sq_collectgarbage(global_vm);
-
- update_game_objects();
- assert(gameobjects_new.size() == 0);
-
- for(GameObjects::iterator i = gameobjects.begin();
- i != gameobjects.end(); ++i) {
- GameObject* object = *i;
- before_object_remove(object);
- object->unref();
- }
-
- for(SpawnPoints::iterator i = spawnpoints.begin(); i != spawnpoints.end();
- ++i)
- delete *i;
-}
-
-Level*
-Sector::get_level()
-{
- return level;
-}
-
-GameObject*
-Sector::parse_object(const std::string& name, const lisp::Lisp& reader)
-{
- if(name == "camera") {
- Camera* camera = new Camera(this, "Camera");
- camera->parse(reader);
- return camera;
- } else if(name == "particles-snow") {
- SnowParticleSystem* partsys = new SnowParticleSystem();
- partsys->parse(reader);
- return partsys;
- } else if(name == "particles-rain") {
- RainParticleSystem* partsys = new RainParticleSystem();
- partsys->parse(reader);
- return partsys;
- } else if(name == "particles-comets") {
- CometParticleSystem* partsys = new CometParticleSystem();
- partsys->parse(reader);
- return partsys;
- } else if(name == "particles-ghosts") {
- GhostParticleSystem* partsys = new GhostParticleSystem();
- partsys->parse(reader);
- return partsys;
- } else if(name == "particles-clouds") {
- CloudParticleSystem* partsys = new CloudParticleSystem();
- partsys->parse(reader);
- return partsys;
- } else if(name == "money") { // for compatibility with old maps
- return new Jumpy(reader);
- }
-
- try {
- return create_object(name, reader);
- } catch(std::exception& e) {
- log_warning << e.what() << "" << std::endl;
- }
-
- return 0;
-}
-
-void
-Sector::parse(const lisp::Lisp& sector)
-{
- bool has_background = false;
- lisp::ListIterator iter(§or);
- while(iter.next()) {
- const std::string& token = iter.item();
- if(token == "name") {
- iter.value()->get(name);
- } else if(token == "gravity") {
- iter.value()->get(gravity);
- } else if(token == "music") {
- iter.value()->get(music);
- } else if(token == "spawnpoint") {
- SpawnPoint* sp = new SpawnPoint(iter.lisp());
- spawnpoints.push_back(sp);
- } else if(token == "init-script") {
- iter.value()->get(init_script);
- } else if(token == "ambient-light") {
- std::vector<float> vColor;
- sector.get( "ambient-light", vColor );
- if(vColor.size() < 3) {
- log_warning << "(ambient-light) requires a color as argument" << std::endl;
- } else {
- ambient_light = Color( vColor );
- }
- } else {
- GameObject* object = parse_object(token, *(iter.lisp()));
- if(object) {
- if(dynamic_cast<Background *>(object)) {
- has_background = true;
- } else if(dynamic_cast<Gradient *>(object)) {
- has_background = true;
- }
- add_object(object);
- }
- }
- }
-
- if(!has_background) {
- Gradient* gradient = new Gradient();
- gradient->set_gradient(Color(0.3, 0.4, 0.75), Color(1, 1, 1));
- add_object(gradient);
- }
-
- update_game_objects();
-
- if(solid_tilemaps.size() < 1) log_warning << "sector '" << name << "' does not contain a solid tile layer." << std::endl;
-
- fix_old_tiles();
- if(!camera) {
- log_warning << "sector '" << name << "' does not contain a camera." << std::endl;
- update_game_objects();
- add_object(new Camera(this, "Camera"));
- }
-
- update_game_objects();
-}
-
-void
-Sector::parse_old_format(const lisp::Lisp& reader)
-{
- name = "main";
- reader.get("gravity", gravity);
-
- std::string backgroundimage;
- if (reader.get("background", backgroundimage) && (backgroundimage != "")) {
- if (backgroundimage == "arctis.png") backgroundimage = "arctis.jpg";
- if (backgroundimage == "arctis2.jpg") backgroundimage = "arctis.jpg";
- if (backgroundimage == "ocean.png") backgroundimage = "ocean.jpg";
- backgroundimage = "images/background/" + backgroundimage;
- if (!PHYSFS_exists(backgroundimage.c_str())) {
- log_warning << "Background image \"" << backgroundimage << "\" not found. Ignoring." << std::endl;
- backgroundimage = "";
- }
- }
-
- float bgspeed = .5;
- reader.get("bkgd_speed", bgspeed);
- bgspeed /= 100;
-
- Color bkgd_top, bkgd_bottom;
- int r = 0, g = 0, b = 128;
- reader.get("bkgd_red_top", r);
- reader.get("bkgd_green_top", g);
- reader.get("bkgd_blue_top", b);
- bkgd_top.red = static_cast<float> (r) / 255.0f;
- bkgd_top.green = static_cast<float> (g) / 255.0f;
- bkgd_top.blue = static_cast<float> (b) / 255.0f;
-
- reader.get("bkgd_red_bottom", r);
- reader.get("bkgd_green_bottom", g);
- reader.get("bkgd_blue_bottom", b);
- bkgd_bottom.red = static_cast<float> (r) / 255.0f;
- bkgd_bottom.green = static_cast<float> (g) / 255.0f;
- bkgd_bottom.blue = static_cast<float> (b) / 255.0f;
-
- if(backgroundimage != "") {
- Background* background = new Background();
- background->set_image(backgroundimage, bgspeed);
- add_object(background);
- } else {
- Gradient* gradient = new Gradient();
- gradient->set_gradient(bkgd_top, bkgd_bottom);
- add_object(gradient);
- }
-
- std::string particlesystem;
- reader.get("particle_system", particlesystem);
- if(particlesystem == "clouds")
- add_object(new CloudParticleSystem());
- else if(particlesystem == "snow")
- add_object(new SnowParticleSystem());
- else if(particlesystem == "rain")
- add_object(new RainParticleSystem());
-
- Vector startpos(100, 170);
- reader.get("start_pos_x", startpos.x);
- reader.get("start_pos_y", startpos.y);
-
- SpawnPoint* spawn = new SpawnPoint;
- spawn->pos = startpos;
- spawn->name = "main";
- spawnpoints.push_back(spawn);
-
- music = "chipdisko.ogg";
- // skip reading music filename. It's all .ogg now, anyway
- /*
- reader.get("music", music);
- */
- music = "music/" + music;
-
- int width = 30, height = 15;
- reader.get("width", width);
- reader.get("height", height);
-
- std::vector<unsigned int> tiles;
- if(reader.get("interactive-tm", tiles)
- || reader.get("tilemap", tiles)) {
- TileMap* tilemap = new TileMap(level->get_tileset());
- tilemap->set(width, height, tiles, LAYER_TILES, true);
-
- // replace tile id 112 (old invisible tile) with 1311 (new invisible tile)
- for(size_t x=0; x < tilemap->get_width(); ++x) {
- for(size_t y=0; y < tilemap->get_height(); ++y) {
- uint32_t id = tilemap->get_tile_id(x, y);
- if(id == 112)
- tilemap->change(x, y, 1311);
- }
- }
-
- if (height < 19) tilemap->resize(width, 19);
- add_object(tilemap);
- }
-
- if(reader.get("background-tm", tiles)) {
- TileMap* tilemap = new TileMap(level->get_tileset());
- tilemap->set(width, height, tiles, LAYER_BACKGROUNDTILES, false);
- if (height < 19) tilemap->resize(width, 19);
- add_object(tilemap);
- }
-
- if(reader.get("foreground-tm", tiles)) {
- TileMap* tilemap = new TileMap(level->get_tileset());
- tilemap->set(width, height, tiles, LAYER_FOREGROUNDTILES, false);
-
- // fill additional space in foreground with tiles of ID 2035 (lightmap/black)
- if (height < 19) tilemap->resize(width, 19, 2035);
-
- add_object(tilemap);
- }
-
- // read reset-points (now spawn-points)
- const lisp::Lisp* resetpoints = reader.get_lisp("reset-points");
- if(resetpoints) {
- lisp::ListIterator iter(resetpoints);
- while(iter.next()) {
- if(iter.item() == "point") {
- Vector sp_pos;
- if(reader.get("x", sp_pos.x) && reader.get("y", sp_pos.y))
- {
- SpawnPoint* sp = new SpawnPoint;
- sp->name = "main";
- sp->pos = sp_pos;
- spawnpoints.push_back(sp);
- }
- } else {
- log_warning << "Unknown token '" << iter.item() << "' in reset-points." << std::endl;
- }
- }
- }
-
- // read objects
- const lisp::Lisp* objects = reader.get_lisp("objects");
- if(objects) {
- lisp::ListIterator iter(objects);
- while(iter.next()) {
- GameObject* object = parse_object(iter.item(), *(iter.lisp()));
- if(object) {
- add_object(object);
- } else {
- log_warning << "Unknown object '" << iter.item() << "' in level." << std::endl;
- }
- }
- }
-
- // add a camera
- Camera* camera = new Camera(this, "Camera");
- add_object(camera);
-
- update_game_objects();
-
- if(solid_tilemaps.size() < 1) log_warning << "sector '" << name << "' does not contain a solid tile layer." << std::endl;
-
- fix_old_tiles();
- update_game_objects();
-}
-
-void
-Sector::fix_old_tiles()
-{
- for(std::list<TileMap*>::iterator i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
- TileMap* solids = *i;
- for(size_t x=0; x < solids->get_width(); ++x) {
- for(size_t y=0; y < solids->get_height(); ++y) {
- uint32_t id = solids->get_tile_id(x, y);
- const Tile *tile = solids->get_tile(x, y);
- Vector pos(solids->get_x_offset() + x*32, solids->get_y_offset() + y*32);
-
- if(id == 112) {
- add_object(new InvisibleBlock(pos));
- solids->change(x, y, 0);
- } else if(tile->getAttributes() & Tile::COIN) {
- add_object(new Coin(pos));
- solids->change(x, y, 0);
- } else if(tile->getAttributes() & Tile::FULLBOX) {
- add_object(new BonusBlock(pos, tile->getData()));
- solids->change(x, y, 0);
- } else if(tile->getAttributes() & Tile::BRICK) {
- add_object(new Brick(pos, tile->getData()));
- solids->change(x, y, 0);
- } else if(tile->getAttributes() & Tile::GOAL) {
- std::string sequence = tile->getData() == 0 ? "endsequence" : "stoptux";
- add_object(new SequenceTrigger(pos, sequence));
- solids->change(x, y, 0);
- }
- }
- }
- }
-
- // add lights for special tiles
- for(GameObjects::iterator i = gameobjects.begin(); i != gameobjects.end(); i++) {
- TileMap* tm = dynamic_cast<TileMap*>(*i);
- if (!tm) continue;
- for(size_t x=0; x < tm->get_width(); ++x) {
- for(size_t y=0; y < tm->get_height(); ++y) {
- uint32_t id = tm->get_tile_id(x, y);
- Vector pos(tm->get_x_offset() + x*32, tm->get_y_offset() + y*32);
- Vector center(pos.x + 16, pos.y + 16);
-
- // torch
- if (id == 1517) {
- float pseudo_rnd = (float)((int)pos.x % 10) / 10;
- add_object(new PulsingLight(center, 1.0f + pseudo_rnd, 0.9f, 1.0f, Color(1.0f, 1.0f, 0.6f, 1.0f)));
- }
- // lava or lavaflow
- if ((id == 173) || (id == 1700) || (id == 1705) || (id == 1706)) {
- // space lights a bit
- if ((((tm->get_tile_id(x-1, y)) != tm->get_tile_id(x,y))
- && (tm->get_tile_id(x, y-1) != tm->get_tile_id(x,y)))
- || ((x % 3 == 0) && (y % 3 == 0))) {
- float pseudo_rnd = (float)((int)pos.x % 10) / 10;
- add_object(new PulsingLight(center, 1.0f + pseudo_rnd, 0.8f, 1.0f, Color(1.0f, 0.3f, 0.0f, 1.0f)));
- }
- }
-
- }
- }
- }
-
-
-}
-
-void
-Sector::write(lisp::Writer& writer)
-{
- writer.write("name", name);
- writer.write("gravity", gravity);
- writer.write("music", music);
-
- // write spawnpoints
- for(SpawnPoints::iterator i = spawnpoints.begin(); i != spawnpoints.end();
- ++i) {
- SpawnPoint* spawn = *i;
- writer.start_list("spawn-points");
- writer.write("name", spawn->name);
- writer.write("x", spawn->pos.x);
- writer.write("y", spawn->pos.y);
- writer.end_list("spawn-points");
- }
-
- // write objects
- for(GameObjects::iterator i = gameobjects.begin();
- i != gameobjects.end(); ++i) {
- Serializable* serializable = dynamic_cast<Serializable*> (*i);
- if(serializable)
- serializable->write(writer);
- }
-}
-
-HSQUIRRELVM
-Sector::run_script(std::istream& in, const std::string& sourcename)
-{
- using namespace Scripting;
-
- // garbage collect thread list
- for(ScriptList::iterator i = scripts.begin();
- i != scripts.end(); ) {
- HSQOBJECT& object = *i;
- HSQUIRRELVM vm = object_to_vm(object);
-
- if(sq_getvmstate(vm) != SQ_VMSTATE_SUSPENDED) {
- sq_release(global_vm, &object);
- i = scripts.erase(i);
- continue;
- }
-
- ++i;
- }
-
- HSQOBJECT object = create_thread(global_vm);
- scripts.push_back(object);
-
- HSQUIRRELVM vm = object_to_vm(object);
-
- // set sector_table as roottable for the thread
- sq_pushobject(vm, sector_table);
- sq_setroottable(vm);
-
- try {
- compile_and_run(vm, in, "Sector " + name + " - " + sourcename);
- } catch(std::exception& e) {
- log_warning << "Error running script: " << e.what() << std::endl;
- }
-
- return vm;
-}
-
-void
-Sector::add_object(GameObject* object)
-{
- // make sure the object isn't already in the list
-#ifdef DEBUG
- for(GameObjects::iterator i = gameobjects.begin(); i != gameobjects.end();
- ++i) {
- if(*i == object) {
- assert("object already added to sector" == 0);
- }
- }
- for(GameObjects::iterator i = gameobjects_new.begin();
- i != gameobjects_new.end(); ++i) {
- if(*i == object) {
- assert("object already added to sector" == 0);
- }
- }
-#endif
-
- object->ref();
- gameobjects_new.push_back(object);
-}
-
-void
-Sector::activate(const std::string& spawnpoint)
-{
- SpawnPoint* sp = 0;
- for(SpawnPoints::iterator i = spawnpoints.begin(); i != spawnpoints.end();
- ++i) {
- if((*i)->name == spawnpoint) {
- sp = *i;
- break;
- }
- }
- if(!sp) {
- log_warning << "Spawnpoint '" << spawnpoint << "' not found." << std::endl;
- if(spawnpoint != "main") {
- activate("main");
- } else {
- activate(Vector(0, 0));
- }
- } else {
- activate(sp->pos);
- }
-}
-
-void
-Sector::activate(const Vector& player_pos)
-{
- if(_current != this) {
- if(_current != NULL)
- _current->deactivate();
- _current = this;
-
- // register sectortable as sector in scripting
- HSQUIRRELVM vm = Scripting::global_vm;
- sq_pushroottable(vm);
- sq_pushstring(vm, "sector", -1);
- sq_pushobject(vm, sector_table);
- if(SQ_FAILED(sq_createslot(vm, -3)))
- throw Scripting::SquirrelError(vm, "Couldn't set sector in roottable");
- sq_pop(vm, 1);
-
- for(GameObjects::iterator i = gameobjects.begin();
- i != gameobjects.end(); ++i) {
- GameObject* object = *i;
-
- try_expose(object);
- }
- }
- try_expose_me();
-
- // spawn smalltux below spawnpoint
- if (!player->is_big()) {
- player->move(player_pos + Vector(0,32));
- } else {
- player->move(player_pos);
- }
-
- // spawning tux in the ground would kill him
- if(!is_free_of_tiles(player->get_bbox())) {
- log_warning << "Tried spawning Tux in solid matter. Compensating." << std::endl;
- Vector npos = player->get_bbox().p1;
- npos.y-=32;
- player->move(npos);
- }
-
- camera->reset(player->get_pos());
- update_game_objects();
-
- //Run default.nut just before init script
- //Check to see if it's in a levelset (info file)
- std::string basedir = FileSystem::dirname(get_level()->filename);
- if(PHYSFS_exists((basedir + "/info").c_str())) {
- try {
- IFileStream in(basedir + "/default.nut");
- run_script(in, "default.nut");
- } catch(std::exception& ) {
- // doesn't exist or erroneous; do nothing
- }
- }
-
- // Run init script
- if(init_script != "") {
- std::istringstream in(init_script);
- run_script(in, "init-script");
- }
-}
-
-void
-Sector::deactivate()
-{
- if(_current != this)
- return;
-
- // remove sector entry from global vm
- HSQUIRRELVM vm = Scripting::global_vm;
- sq_pushroottable(vm);
- sq_pushstring(vm, "sector", -1);
- if(SQ_FAILED(sq_deleteslot(vm, -2, SQFalse)))
- throw Scripting::SquirrelError(vm, "Couldn't unset sector in roottable");
- sq_pop(vm, 1);
-
- for(GameObjects::iterator i = gameobjects.begin();
- i != gameobjects.end(); ++i) {
- GameObject* object = *i;
-
- try_unexpose(object);
- }
-
- try_unexpose_me();
- _current = NULL;
-}
-
-Rect
-Sector::get_active_region()
-{
- return Rect(
- camera->get_translation() - Vector(1600, 1200),
- camera->get_translation() + Vector(1600, 1200) + Vector(SCREEN_WIDTH,SCREEN_HEIGHT));
-}
-
-void
-Sector::update(float elapsed_time)
-{
- player->check_bounds(camera);
-
- /* update objects */
- for(GameObjects::iterator i = gameobjects.begin();
- i != gameobjects.end(); ++i) {
- GameObject* object = *i;
- if(!object->is_valid())
- continue;
-
- object->update(elapsed_time);
- }
-
- /* Handle all possible collisions. */
- handle_collisions();
- update_game_objects();
-}
-
-void
-Sector::update_game_objects()
-{
- /** cleanup marked objects */
- for(std::vector<GameObject*>::iterator i = gameobjects.begin();
- i != gameobjects.end(); /* nothing */) {
- GameObject* object = *i;
-
- if(object->is_valid()) {
- ++i;
- continue;
- }
-
- before_object_remove(object);
-
- object->unref();
- i = gameobjects.erase(i);
- }
-
- /* add newly created objects */
- for(std::vector<GameObject*>::iterator i = gameobjects_new.begin();
- i != gameobjects_new.end(); ++i)
- {
- GameObject* object = *i;
-
- before_object_add(object);
-
- gameobjects.push_back(object);
- }
- gameobjects_new.clear();
-
- /* update solid_tilemaps list */
- //FIXME: this could be more efficient
- solid_tilemaps.clear();
- for(std::vector<GameObject*>::iterator i = gameobjects.begin();
- i != gameobjects.end(); ++i)
- {
- TileMap* tm = dynamic_cast<TileMap*>(*i);
- if (!tm) continue;
- if (tm->is_solid()) solid_tilemaps.push_back(tm);
- }
-
-}
-
-bool
-Sector::before_object_add(GameObject* object)
-{
- Bullet* bullet = dynamic_cast<Bullet*> (object);
- if(bullet != NULL) {
- bullets.push_back(bullet);
- }
-
- MovingObject* movingobject = dynamic_cast<MovingObject*> (object);
- if(movingobject != NULL) {
- moving_objects.push_back(movingobject);
- }
-
- Portable* portable = dynamic_cast<Portable*> (object);
- if(portable != NULL) {
- portables.push_back(portable);
- }
-
- TileMap* tilemap = dynamic_cast<TileMap*> (object);
- if(tilemap != NULL && tilemap->is_solid()) {
- solid_tilemaps.push_back(tilemap);
- }
-
- Camera* camera = dynamic_cast<Camera*> (object);
- if(camera != NULL) {
- if(this->camera != 0) {
- log_warning << "Multiple cameras added. Ignoring" << std::endl;
- return false;
- }
- this->camera = camera;
- }
-
- Player* player = dynamic_cast<Player*> (object);
- if(player != NULL) {
- if(this->player != 0) {
- log_warning << "Multiple players added. Ignoring" << std::endl;
- return false;
- }
- this->player = player;
- }
-
- DisplayEffect* effect = dynamic_cast<DisplayEffect*> (object);
- if(effect != NULL) {
- if(this->effect != 0) {
- log_warning << "Multiple DisplayEffects added. Ignoring" << std::endl;
- return false;
- }
- this->effect = effect;
- }
-
- UsesPhysic *physic_object = dynamic_cast<UsesPhysic *>(object);
- if(physic_object)
- {
- physic_object->physic.set_gravity(gravity);
- }
-
-
- if(_current == this) {
- try_expose(object);
- }
-
- return true;
-}
-
-void
-Sector::try_expose(GameObject* object)
-{
- ScriptInterface* interface = dynamic_cast<ScriptInterface*> (object);
- if(interface != NULL) {
- HSQUIRRELVM vm = Scripting::global_vm;
- sq_pushobject(vm, sector_table);
- interface->expose(vm, -1);
- sq_pop(vm, 1);
- }
-}
-
-void
-Sector::try_expose_me()
-{
- HSQUIRRELVM vm = Scripting::global_vm;
- sq_pushobject(vm, sector_table);
- Scripting::SSector* interface = static_cast<Scripting::SSector*> (this);
- expose_object(vm, -1, interface, "settings", false);
- sq_pop(vm, 1);
-}
-
-void
-Sector::before_object_remove(GameObject* object)
-{
- Portable* portable = dynamic_cast<Portable*> (object);
- if(portable != NULL) {
- portables.erase(std::find(portables.begin(), portables.end(), portable));
- }
- Bullet* bullet = dynamic_cast<Bullet*> (object);
- if(bullet != NULL) {
- bullets.erase(std::find(bullets.begin(), bullets.end(), bullet));
- }
- MovingObject* moving_object = dynamic_cast<MovingObject*> (object);
- if(moving_object != NULL) {
- moving_objects.erase(
- std::find(moving_objects.begin(), moving_objects.end(), moving_object));
- }
-
- if(_current == this)
- try_unexpose(object);
-}
-
-void
-Sector::try_unexpose(GameObject* object)
-{
- ScriptInterface* interface = dynamic_cast<ScriptInterface*> (object);
- if(interface != NULL) {
- HSQUIRRELVM vm = Scripting::global_vm;
- SQInteger oldtop = sq_gettop(vm);
- sq_pushobject(vm, sector_table);
- try {
- interface->unexpose(vm, -1);
- } catch(std::exception& e) {
- log_warning << "Couldn't unregister object: " << e.what() << std::endl;
- }
- sq_settop(vm, oldtop);
- }
-}
-
-void
-Sector::try_unexpose_me()
-{
- HSQUIRRELVM vm = Scripting::global_vm;
- SQInteger oldtop = sq_gettop(vm);
- sq_pushobject(vm, sector_table);
- try {
- Scripting::unexpose_object(vm, -1, "settings");
- } catch(std::exception& e) {
- log_warning << "Couldn't unregister object: " << e.what() << std::endl;
- }
- sq_settop(vm, oldtop);
-}
-void
-Sector::draw(DrawingContext& context)
-{
- context.set_ambient_color( ambient_light );
- context.push_transform();
- context.set_translation(camera->get_translation());
-
- for(GameObjects::iterator i = gameobjects.begin();
- i != gameobjects.end(); ++i) {
- GameObject* object = *i;
- if(!object->is_valid())
- continue;
-
- if (draw_solids_only)
- {
- TileMap* tm = dynamic_cast<TileMap*>(object);
- if (tm && !tm->is_solid())
- continue;
- }
-
- object->draw(context);
- }
-
- if(show_collrects) {
- Color col(0.2f, 0.2f, 0.2f, 0.7f);
- for(MovingObjects::iterator i = moving_objects.begin();
- i != moving_objects.end(); ++i) {
- MovingObject* object = *i;
- const Rect& rect = object->get_bbox();
-
- context.draw_filled_rect(rect, col, LAYER_FOREGROUND1 + 10);
- }
- }
-
- context.pop_transform();
-}
-
-/*-------------------------------------------------------------------------
- * Collision Detection
- *-------------------------------------------------------------------------*/
-
-/** r1 is supposed to be moving, r2 a solid object */
-void check_collisions(collision::Constraints* constraints,
- const Vector& movement, const Rect& r1, const Rect& r2,
- GameObject* object = NULL, MovingObject* other = NULL, const Vector& addl_ground_movement = Vector(0,0))
-{
- if(!collision::intersects(r1, r2))
- return;
-
- MovingObject *moving_object = dynamic_cast<MovingObject*> (object);
- CollisionHit dummy;
- if(other != NULL && !other->collides(*object, dummy))
- return;
- if(moving_object != NULL && !moving_object->collides(*other, dummy))
- return;
-
- // calculate intersection
- float itop = r1.get_bottom() - r2.get_top();
- float ibottom = r2.get_bottom() - r1.get_top();
- float ileft = r1.get_right() - r2.get_left();
- float iright = r2.get_right() - r1.get_left();
-
- if(fabsf(movement.y) > fabsf(movement.x)) {
- if(ileft < SHIFT_DELTA) {
- constraints->right = std::min(constraints->right, r2.get_left());
- return;
- } else if(iright < SHIFT_DELTA) {
- constraints->left = std::max(constraints->left, r2.get_right());
- return;
- }
- } else {
- // shiftout bottom/top
- if(itop < SHIFT_DELTA) {
- constraints->bottom = std::min(constraints->bottom, r2.get_top());
- return;
- } else if(ibottom < SHIFT_DELTA) {
- constraints->top = std::max(constraints->top, r2.get_bottom());
- return;
- }
- }
-
- constraints->ground_movement += addl_ground_movement;
- if(other != NULL) {
- HitResponse response = other->collision(*object, dummy);
- if(response == PASSTHROUGH)
- return;
-
- if(other->get_movement() != Vector(0, 0)) {
- // TODO what todo when we collide with 2 moving objects?!?
- constraints->ground_movement = other->get_movement();
- }
- }
-
- float vert_penetration = std::min(itop, ibottom);
- float horiz_penetration = std::min(ileft, iright);
- if(vert_penetration < horiz_penetration) {
- if(itop < ibottom) {
- constraints->bottom = std::min(constraints->bottom, r2.get_top());
- constraints->hit.bottom = true;
- } else {
- constraints->top = std::max(constraints->top, r2.get_bottom());
- constraints->hit.top = true;
- }
- } else {
- if(ileft < iright) {
- constraints->right = std::min(constraints->right, r2.get_left());
- constraints->hit.right = true;
- } else {
- constraints->left = std::max(constraints->left, r2.get_right());
- constraints->hit.left = true;
- }
- }
-}
-
-void
-Sector::collision_tilemap(collision::Constraints* constraints,
- const Vector& movement, const Rect& dest) const
-{
- // calculate rectangle where the object will move
- float x1 = dest.get_left();
- float x2 = dest.get_right();
- float y1 = dest.get_top();
- float y2 = dest.get_bottom();
-
- for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
- TileMap* solids = *i;
-
- // test with all tiles in this rectangle
- int starttilex = int(x1 - solids->get_x_offset()) / 32;
- int starttiley = int(y1 - solids->get_y_offset()) / 32;
- int max_x = int(x2 - solids->get_x_offset());
- int max_y = int(y2+1 - solids->get_y_offset());
-
- for(int x = starttilex; x*32 < max_x; ++x) {
- for(int y = starttiley; y*32 < max_y; ++y) {
- const Tile* tile = solids->get_tile(x, y);
- if(!tile)
- continue;
- // skip non-solid tiles
- if((tile->getAttributes() & Tile::SOLID) == 0)
- continue;
- // only handle unisolid when the player is falling down and when he was
- // above the tile before
- if(tile->getAttributes() & Tile::UNISOLID) {
- if(movement.y <= 0 || dest.get_bottom() - movement.y - SHIFT_DELTA > y*32)
- continue;
- }
-
- if(tile->getAttributes() & Tile::SLOPE) { // slope tile
- AATriangle triangle;
- Vector p1(x*32 + solids->get_x_offset(), y*32 + solids->get_y_offset());
- Vector p2((x+1)*32 + solids->get_x_offset(), (y+1)*32 + solids->get_y_offset());
- triangle = AATriangle(p1, p2, tile->getData());
-
- collision::rectangle_aatriangle(constraints, dest, triangle, solids->get_movement());
- } else { // normal rectangular tile
- Rect rect(x*32 + solids->get_x_offset(), y*32 + solids->get_y_offset(), (x+1)*32 + solids->get_x_offset(), (y+1)*32 + solids->get_y_offset());
- check_collisions(constraints, movement, dest, rect, NULL, NULL, solids->get_movement());
- }
- }
- }
- }
-}
-
-uint32_t
-Sector::collision_tile_attributes(const Rect& dest) const
-{
- float x1 = dest.p1.x;
- float y1 = dest.p1.y;
- float x2 = dest.p2.x;
- float y2 = dest.p2.y + SHIFT_DELTA;
-
- uint32_t result = 0;
- for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
- TileMap* solids = *i;
-
- // test with all tiles in this rectangle
- int starttilex = int(x1 - solids->get_x_offset()) / 32;
- int starttiley = int(y1 - solids->get_y_offset()) / 32;
- int max_x = int(x2 - solids->get_x_offset());
- int max_y = int(y2+1 - solids->get_y_offset());
-
- for(int x = starttilex; x*32 < max_x; ++x) {
- for(int y = starttiley; y*32 < max_y; ++y) {
- const Tile* tile = solids->get_tile(x, y);
- if(!tile)
- continue;
- result |= tile->getAttributes();
- }
- }
- }
-
- return result;
-}
-
-/** fills in CollisionHit and Normal vector of 2 intersecting rectangle */
-static void get_hit_normal(const Rect& r1, const Rect& r2, CollisionHit& hit,
- Vector& normal)
-{
- float itop = r1.get_bottom() - r2.get_top();
- float ibottom = r2.get_bottom() - r1.get_top();
- float ileft = r1.get_right() - r2.get_left();
- float iright = r2.get_right() - r1.get_left();
-
- float vert_penetration = std::min(itop, ibottom);
- float horiz_penetration = std::min(ileft, iright);
- if(vert_penetration < horiz_penetration) {
- if(itop < ibottom) {
- hit.bottom = true;
- normal.y = vert_penetration;
- } else {
- hit.top = true;
- normal.y = -vert_penetration;
- }
- } else {
- if(ileft < iright) {
- hit.right = true;
- normal.x = horiz_penetration;
- } else {
- hit.left = true;
- normal.x = -horiz_penetration;
- }
- }
-}
-
-void
-Sector::collision_object(MovingObject* object1, MovingObject* object2) const
-{
- using namespace collision;
-
- const Rect& r1 = object1->dest;
- const Rect& r2 = object2->dest;
-
- CollisionHit hit;
- if(intersects(object1->dest, object2->dest)) {
- Vector normal;
- get_hit_normal(r1, r2, hit, normal);
-
- if(!object1->collides(*object2, hit))
- return;
- std::swap(hit.left, hit.right);
- std::swap(hit.top, hit.bottom);
- if(!object2->collides(*object1, hit))
- return;
- std::swap(hit.left, hit.right);
- std::swap(hit.top, hit.bottom);
-
- HitResponse response1 = object1->collision(*object2, hit);
- std::swap(hit.left, hit.right);
- std::swap(hit.top, hit.bottom);
- HitResponse response2 = object2->collision(*object1, hit);
- if(response1 == CONTINUE && response2 == CONTINUE) {
- normal *= (0.5 + DELTA);
- object1->dest.move(-normal);
- object2->dest.move(normal);
- } else if (response1 == CONTINUE && response2 == FORCE_MOVE) {
- normal *= (1 + DELTA);
- object1->dest.move(-normal);
- } else if (response1 == FORCE_MOVE && response2 == CONTINUE) {
- normal *= (1 + DELTA);
- object2->dest.move(normal);
- }
- }
-}
-
-void
-Sector::collision_static(collision::Constraints* constraints,
- const Vector& movement, const Rect& dest,
- GameObject& object)
-{
- collision_tilemap(constraints, movement, dest);
-
- // collision with other (static) objects
- for(MovingObjects::iterator i = moving_objects.begin();
- i != moving_objects.end(); ++i) {
- MovingObject* moving_object = *i;
- if(moving_object->get_group() != COLGROUP_STATIC
- && moving_object->get_group() != COLGROUP_MOVING_STATIC)
- continue;
- if(!moving_object->is_valid())
- continue;
-
- if(moving_object != &object)
- check_collisions(constraints, movement, dest, moving_object->bbox,
- &object, moving_object);
- }
-}
-
-void
-Sector::collision_static_constrains(MovingObject& object)
-{
- using namespace collision;
- float infinity = (std::numeric_limits<float>::has_infinity ? std::numeric_limits<float>::infinity() : std::numeric_limits<float>::max());
-
- Constraints constraints;
- Vector movement = object.get_movement();
- Rect& dest = object.dest;
- float owidth = object.get_bbox().get_width();
- float oheight = object.get_bbox().get_height();
-
- for(int i = 0; i < 2; ++i) {
- collision_static(&constraints, Vector(0, movement.y), dest, object);
- if(!constraints.has_constraints())
- break;
-
- // apply calculated horizontal constraints
- if(constraints.bottom < infinity) {
- float height = constraints.bottom - constraints.top;
- if(height < oheight) {
- // we're crushed, but ignore this for now, we'll get this again
- // later if we're really crushed or things will solve itself when
- // looking at the vertical constraints
- }
- dest.p2.y = constraints.bottom - DELTA;
- dest.p1.y = dest.p2.y - oheight;
- } else if(constraints.top > -infinity) {
- dest.p1.y = constraints.top + DELTA;
- dest.p2.y = dest.p1.y + oheight;
- }
- }
- if(constraints.has_constraints()) {
- if(constraints.hit.bottom) {
- dest.move(constraints.ground_movement);
- }
- if(constraints.hit.top || constraints.hit.bottom) {
- constraints.hit.left = false;
- constraints.hit.right = false;
- object.collision_solid(constraints.hit);
- }
- }
-
- constraints = Constraints();
- for(int i = 0; i < 2; ++i) {
- collision_static(&constraints, movement, dest, object);
- if(!constraints.has_constraints())
- break;
-
- // apply calculated vertical constraints
- if(constraints.right < infinity) {
- float width = constraints.right - constraints.left;
- if(width + SHIFT_DELTA < owidth) {
-#if 0
- printf("Object %p crushed horizontally... L:%f R:%f\n", &object,
- constraints.left, constraints.right);
-#endif
- CollisionHit h;
- h.left = true;
- h.right = true;
- h.crush = true;
- object.collision_solid(h);
- } else {
- dest.p2.x = constraints.right - DELTA;
- dest.p1.x = dest.p2.x - owidth;
- }
- } else if(constraints.left > -infinity) {
- dest.p1.x = constraints.left + DELTA;
- dest.p2.x = dest.p1.x + owidth;
- }
- }
-
- if(constraints.has_constraints()) {
- if( constraints.hit.left || constraints.hit.right
- || constraints.hit.top || constraints.hit.bottom
- || constraints.hit.crush )
- object.collision_solid(constraints.hit);
- }
-
- // an extra pass to make sure we're not crushed horizontally
- constraints = Constraints();
- collision_static(&constraints, movement, dest, object);
- if(constraints.bottom < infinity) {
- float height = constraints.bottom - constraints.top;
- if(height + SHIFT_DELTA < oheight) {
-#if 0
- printf("Object %p crushed vertically...\n", &object);
-#endif
- CollisionHit h;
- h.top = true;
- h.bottom = true;
- h.crush = true;
- object.collision_solid(h);
- }
- }
-}
-
-namespace {
- const float MAX_SPEED = 16.0f;
-}
-
-void
-Sector::handle_collisions()
-{
- using namespace collision;
-
- // calculate destination positions of the objects
- for(MovingObjects::iterator i = moving_objects.begin();
- i != moving_objects.end(); ++i) {
- MovingObject* moving_object = *i;
- Vector mov = moving_object->get_movement();
-
- // make sure movement is never faster than MAX_SPEED. Norm is pretty fat, so two addl. checks are done before.
- if (((mov.x > MAX_SPEED * M_SQRT1_2) || (mov.y > MAX_SPEED * M_SQRT1_2)) && (mov.norm() > MAX_SPEED)) {
- moving_object->movement = mov.unit() * MAX_SPEED;
- //log_debug << "Temporarily reduced object's speed of " << mov.norm() << " to " << moving_object->movement.norm() << "." << std::endl;
- }
-
- moving_object->dest = moving_object->get_bbox();
- moving_object->dest.move(moving_object->get_movement());
- }
-
- // part1: COLGROUP_MOVING vs COLGROUP_STATIC and tilemap
- for(MovingObjects::iterator i = moving_objects.begin();
- i != moving_objects.end(); ++i) {
- MovingObject* moving_object = *i;
- if((moving_object->get_group() != COLGROUP_MOVING
- && moving_object->get_group() != COLGROUP_MOVING_STATIC
- && moving_object->get_group() != COLGROUP_MOVING_ONLY_STATIC)
- || !moving_object->is_valid())
- continue;
-
- collision_static_constrains(*moving_object);
- }
-
-
- // part2: COLGROUP_MOVING vs tile attributes
- for(MovingObjects::iterator i = moving_objects.begin();
- i != moving_objects.end(); ++i) {
- MovingObject* moving_object = *i;
- if((moving_object->get_group() != COLGROUP_MOVING
- && moving_object->get_group() != COLGROUP_MOVING_STATIC
- && moving_object->get_group() != COLGROUP_MOVING_ONLY_STATIC)
- || !moving_object->is_valid())
- continue;
-
- uint32_t tile_attributes = collision_tile_attributes(moving_object->dest);
- if(tile_attributes > Tile::FIRST_INTERESTING_FLAG) {
- moving_object->collision_tile(tile_attributes);
- }
- }
-
- // part2.5: COLGROUP_MOVING vs COLGROUP_TOUCHABLE
- for(MovingObjects::iterator i = moving_objects.begin();
- i != moving_objects.end(); ++i) {
- MovingObject* moving_object = *i;
- if((moving_object->get_group() != COLGROUP_MOVING
- && moving_object->get_group() != COLGROUP_MOVING_STATIC)
- || !moving_object->is_valid())
- continue;
-
- for(MovingObjects::iterator i2 = moving_objects.begin();
- i2 != moving_objects.end(); ++i2) {
- MovingObject* moving_object_2 = *i2;
- if(moving_object_2->get_group() != COLGROUP_TOUCHABLE
- || !moving_object_2->is_valid())
- continue;
-
- if(intersects(moving_object->dest, moving_object_2->dest)) {
- Vector normal;
- CollisionHit hit;
- get_hit_normal(moving_object->dest, moving_object_2->dest,
- hit, normal);
- if(!moving_object->collides(*moving_object_2, hit))
- continue;
- if(!moving_object_2->collides(*moving_object, hit))
- continue;
-
- moving_object->collision(*moving_object_2, hit);
- moving_object_2->collision(*moving_object, hit);
- }
- }
- }
-
- // part3: COLGROUP_MOVING vs COLGROUP_MOVING
- for(MovingObjects::iterator i = moving_objects.begin();
- i != moving_objects.end(); ++i) {
- MovingObject* moving_object = *i;
-
- if((moving_object->get_group() != COLGROUP_MOVING
- && moving_object->get_group() != COLGROUP_MOVING_STATIC)
- || !moving_object->is_valid())
- continue;
-
- for(MovingObjects::iterator i2 = i+1;
- i2 != moving_objects.end(); ++i2) {
- MovingObject* moving_object_2 = *i2;
- if((moving_object_2->get_group() != COLGROUP_MOVING
- && moving_object_2->get_group() != COLGROUP_MOVING_STATIC)
- || !moving_object_2->is_valid())
- continue;
-
- collision_object(moving_object, moving_object_2);
- }
- }
-
- // apply object movement
- for(MovingObjects::iterator i = moving_objects.begin();
- i != moving_objects.end(); ++i) {
- MovingObject* moving_object = *i;
-
- moving_object->bbox = moving_object->dest;
- moving_object->movement = Vector(0, 0);
- }
-}
-
-bool
-Sector::is_free_of_tiles(const Rect& rect, const bool ignoreUnisolid) const
-{
- using namespace collision;
-
- for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
- TileMap* solids = *i;
-
- // test with all tiles in this rectangle
- int starttilex = int(rect.p1.x - solids->get_x_offset()) / 32;
- int starttiley = int(rect.p1.y - solids->get_y_offset()) / 32;
- int max_x = int(rect.p2.x - solids->get_x_offset());
- int max_y = int(rect.p2.y - solids->get_y_offset());
-
- for(int x = starttilex; x*32 <= max_x; ++x) {
- for(int y = starttiley; y*32 <= max_y; ++y) {
- const Tile* tile = solids->get_tile(x, y);
- if(!tile) continue;
- if(tile->getAttributes() & Tile::SLOPE) {
- AATriangle triangle;
- Vector p1(x*32 + solids->get_x_offset(), y*32 + solids->get_y_offset());
- Vector p2((x+1)*32 + solids->get_x_offset(), (y+1)*32 + solids->get_y_offset());
- triangle = AATriangle(p1, p2, tile->getData());
- Constraints constraints;
- if(collision::rectangle_aatriangle(&constraints, rect, triangle) && (!ignoreUnisolid || !(tile->getAttributes() & Tile::UNISOLID))) return false;
- }
- if((tile->getAttributes() & Tile::SOLID) && (!ignoreUnisolid || !(tile->getAttributes() & Tile::UNISOLID))) return false;
- }
- }
- }
-
- return true;
-}
-
-bool
-Sector::is_free_of_statics(const Rect& rect, const MovingObject* ignore_object, const bool ignoreUnisolid) const
-{
- using namespace collision;
-
- if (!is_free_of_tiles(rect, ignoreUnisolid)) return false;
-
- for(MovingObjects::const_iterator i = moving_objects.begin();
- i != moving_objects.end(); ++i) {
- const MovingObject* moving_object = *i;
- if (moving_object == ignore_object) continue;
- if (!moving_object->is_valid()) continue;
- if (moving_object->get_group() == COLGROUP_STATIC) {
- if(intersects(rect, moving_object->get_bbox())) return false;
- }
- }
-
- return true;
-}
-
-bool
-Sector::is_free_of_movingstatics(const Rect& rect, const MovingObject* ignore_object) const
-{
- using namespace collision;
-
- if (!is_free_of_tiles(rect)) return false;
-
- for(MovingObjects::const_iterator i = moving_objects.begin();
- i != moving_objects.end(); ++i) {
- const MovingObject* moving_object = *i;
- if (moving_object == ignore_object) continue;
- if (!moving_object->is_valid()) continue;
- if ((moving_object->get_group() == COLGROUP_MOVING)
- || (moving_object->get_group() == COLGROUP_MOVING_STATIC)
- || (moving_object->get_group() == COLGROUP_STATIC)) {
- if(intersects(rect, moving_object->get_bbox())) return false;
- }
- }
-
- return true;
-}
-
-bool
-Sector::add_bullet(const Vector& pos, float xm, Direction dir)
-{
- // TODO remove this function and move these checks elsewhere...
-
- Bullet* new_bullet = 0;
- if((player_status->bonus == FIRE_BONUS &&
- (int)bullets.size() >= player_status->max_fire_bullets) ||
- (player_status->bonus == ICE_BONUS &&
- (int)bullets.size() >= player_status->max_ice_bullets))
- return false;
- new_bullet = new Bullet(pos, xm, dir, player_status->bonus);
- add_object(new_bullet);
-
- sound_manager->play("sounds/shoot.wav");
-
- return true;
-}
-
-bool
-Sector::add_smoke_cloud(const Vector& pos)
-{
- add_object(new SmokeCloud(pos));
- return true;
-}
-
-void
-Sector::play_music(MusicType type)
-{
- currentmusic = type;
- switch(currentmusic) {
- case LEVEL_MUSIC:
- sound_manager->play_music(music);
- break;
- case HERRING_MUSIC:
- sound_manager->play_music("music/invincible.music");
- break;
- case HERRING_WARNING_MUSIC:
- sound_manager->stop_music(TUX_INVINCIBLE_TIME_WARNING);
- break;
- default:
- sound_manager->play_music("");
- break;
- }
-}
-
-MusicType
-Sector::get_music_type()
-{
- return currentmusic;
-}
-
-int
-Sector::get_total_badguys()
-{
- int total_badguys = 0;
- for(GameObjects::iterator i = gameobjects.begin();
- i != gameobjects.end(); ++i) {
- BadGuy* badguy = dynamic_cast<BadGuy*> (*i);
- if (badguy && badguy->countMe)
- total_badguys++;
- }
-
- return total_badguys;
-}
-
-bool
-Sector::inside(const Rect& rect) const
-{
- for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
- TileMap* solids = *i;
- bool horizontally = ((rect.p2.x >= 0 + solids->get_x_offset()) && (rect.p1.x <= solids->get_width() * 32 + solids->get_x_offset()));
- bool vertically = (rect.p1.y <= solids->get_height() * 32 + solids->get_y_offset());
-
- if (horizontally && vertically)
- return true;
- }
- return false;
-}
-
-float
-Sector::get_width() const
-{
- float width = 0;
- for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin();
- i != solid_tilemaps.end(); i++) {
- TileMap* solids = *i;
- if ((solids->get_width() * 32 + solids->get_x_offset()) > width) {
- width = solids->get_width() * 32 + solids->get_x_offset();
- }
- }
-
- return width;
-}
-
-float
-Sector::get_height() const
-{
- float height = 0;
- for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin();
- i != solid_tilemaps.end(); i++) {
- TileMap* solids = *i;
- if ((solids->get_height() * 32 + solids->get_y_offset()) > height) {
- height = solids->get_height() * 32 + solids->get_y_offset();
- }
- }
-
- return height;
-}
-
-void
-Sector::change_solid_tiles(uint32_t old_tile_id, uint32_t new_tile_id)
-{
- for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
- TileMap* solids = *i;
- solids->change_all(old_tile_id, new_tile_id);
- }
-}
-
-
-void
-Sector::set_ambient_light(float red, float green, float blue)
-{
- ambient_light.red = red;
- ambient_light.green = green;
- ambient_light.blue = blue;
-}
-
-float
-Sector::get_ambient_red()
-{
- return ambient_light.red;
-}
-
-float
-Sector::get_ambient_green()
-{
- return ambient_light.green;
-}
-
-float
-Sector::get_ambient_blue()
-{
- return ambient_light.blue;
-}
-
-void
-Sector::set_gravity(float gravity)
-{
- log_warning << "Changing a Sector's gravitational constant might have unforeseen side-effects" << std::endl;
-
- this->gravity = gravity;
-
- for(GameObjects::iterator i = gameobjects.begin(); i != gameobjects.end(); ++i) {
- GameObject* game_object = *i;
- if(!game_object) continue;
- if(!game_object->is_valid()) continue;
- UsesPhysic *physics_object = dynamic_cast<UsesPhysic*>(game_object);
- if (!physics_object) continue;
-
- physics_object->physic.set_gravity(gravity);
- }
-}
-
+++ /dev/null
-// $Id$
-//
-// SuperTux - A Jump'n Run
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#ifndef SUPERTUX_SECTOR_H
-#define SUPERTUX_SECTOR_H
-
-#include <vector>
-#include <list>
-#include <memory>
-#include <squirrel.h>
-#include <stdint.h>
-
-#include "direction.hpp"
-#include "video/color.hpp"
-#include "scripting/ssector.hpp"
-
-namespace lisp {
-class Lisp;
-class Writer;
-}
-namespace collision {
-class Constraints;
-}
-
-class Vector;
-class Rect;
-class Sprite;
-class GameObject;
-class Player;
-class Camera;
-class TileMap;
-class Bullet;
-class ScriptInterpreter;
-class SpawnPoint;
-class MovingObject;
-class CollisionHit;
-class Level;
-class Portable;
-class DrawingContext;
-class DisplayEffect;
-
-enum MusicType {
- LEVEL_MUSIC,
- HERRING_MUSIC,
- HERRING_WARNING_MUSIC
-};
-
-/**
- * Represents one of (potentially) multiple, separate parts of a Level.
- *
- * Sectors contain GameObjects, e.g. Badguys and Players.
- */
-class Sector : public Scripting::SSector
-{
-public:
- Sector(Level* parent);
- ~Sector();
-
- /// get parent level
- Level* get_level();
-
- /// read sector from lisp file
- void parse(const lisp::Lisp& lisp);
- void parse_old_format(const lisp::Lisp& lisp);
- /// write sector to lisp file
- void write(lisp::Writer& writer);
-
- /// activates this sector (change music, initialize player class, ...)
- void activate(const std::string& spawnpoint);
- void activate(const Vector& player_pos);
- void deactivate();
-
- void update(float elapsed_time);
- void update_game_objects();
-
- void draw(DrawingContext& context);
-
- /**
- * runs a script in the context of the sector (sector_table will be the
- * roottable of this squirrel VM)
- */
- HSQUIRRELVM run_script(std::istream& in, const std::string& sourcename);
-
- /// adds a gameobject
- void add_object(GameObject* object);
-
- void set_name(const std::string& name)
- { this->name = name; }
- const std::string& get_name() const
- { return name; }
-
- /**
- * tests if a given rectangle is inside the sector
- * (a rectangle that is on top of the sector is considered inside)
- */
- bool inside(const Rect& rectangle) const;
-
- void play_music(MusicType musictype);
- MusicType get_music_type();
-
- bool add_bullet(const Vector& pos, float xm, Direction dir);
- bool add_smoke_cloud(const Vector& pos);
-
- /** get currently activated sector. */
- static Sector* current()
- { return _current; }
-
- /** Get total number of badguys */
- int get_total_badguys();
-
- /** Get total number of GameObjects of given type */
- template<class T> int get_total_count()
- {
- int total = 0;
- for(GameObjects::iterator i = gameobjects.begin(); i != gameobjects.end(); ++i) {
- if (dynamic_cast<T*>(*i)) total++;
- }
- return total;
- }
-
- void collision_tilemap(collision::Constraints* constraints,
- const Vector& movement, const Rect& dest) const;
-
- /**
- * Checks if the specified rectangle is free of (solid) tiles.
- * Note that this does not include static objects, e.g. bonus blocks.
- */
- bool is_free_of_tiles(const Rect& rect, const bool ignoreUnisolid = false) const;
- /**
- * Checks if the specified rectangle is free of both
- * 1.) solid tiles and
- * 2.) MovingObjects in COLGROUP_STATIC.
- * Note that this does not include badguys or players.
- */
- bool is_free_of_statics(const Rect& rect, const MovingObject* ignore_object = 0, const bool ignoreUnisolid = false) const;
- /**
- * Checks if the specified rectangle is free of both
- * 1.) solid tiles and
- * 2.) MovingObjects in COLGROUP_STATIC, COLGROUP_MOVINGSTATIC or COLGROUP_MOVING.
- * This includes badguys and players.
- */
- bool is_free_of_movingstatics(const Rect& rect, const MovingObject* ignore_object = 0) const;
-
- /**
- * returns a list of players currently in the sector
- */
- std::vector<Player*> get_players() {
- return std::vector<Player*>(1, this->player);
- }
-
- Rect get_active_region();
-
- /**
- * returns the width (in px) of a sector)
- */
- float get_width() const;
-
- /**
- * returns the height (in px) of a sector)
- */
- float get_height() const;
-
- /**
- * globally changes solid tilemaps' tile ids
- */
- void change_solid_tiles(uint32_t old_tile_id, uint32_t new_tile_id);
-
- typedef std::vector<GameObject*> GameObjects;
- typedef std::vector<MovingObject*> MovingObjects;
- typedef std::vector<SpawnPoint*> SpawnPoints;
- typedef std::vector<Portable*> Portables;
-
- // --- Scripting ---
- /**
- * get/set color of ambient light
- */
- void set_ambient_light(float red, float green, float blue);
- float get_ambient_red();
- float get_ambient_green();
- float get_ambient_blue();
-
- /**
- * set gravity throughout sector
- */
- void set_gravity(float gravity);
-
-private:
- Level* level; /**< Parent level containing this sector */
- uint32_t collision_tile_attributes(const Rect& dest) const;
-
- void before_object_remove(GameObject* object);
- bool before_object_add(GameObject* object);
-
- void try_expose(GameObject* object);
- void try_unexpose(GameObject* object);
- void try_expose_me();
- void try_unexpose_me();
-
- /** Checks for all possible collisions. And calls the
- collision_handlers, which the collision_objects provide for this
- case (or not). */
- void handle_collisions();
-
- /**
- * Does collision detection between 2 objects and does instant
- * collision response handling in case of a collision
- */
- void collision_object(MovingObject* object1, MovingObject* object2) const;
-
- /**
- * Does collision detection of an object against all other static
- * objects (and the tilemap) in the level. Collision response is done
- * for the first hit in time. (other hits get ignored, the function
- * should be called repeatedly to resolve those)
- *
- * returns true if the collision detection should be aborted for this object
- * (because of ABORT_MOVE in the collision response or no collisions)
- */
- void collision_static(collision::Constraints* constraints,
- const Vector& movement, const Rect& dest, GameObject& object);
-
- void collision_static_constrains(MovingObject& object);
-
- GameObject* parse_object(const std::string& name, const lisp::Lisp& lisp);
-
- void fix_old_tiles();
-
- static Sector* _current;
-
- std::string name;
-
- std::vector<Bullet*> bullets;
-
- std::string init_script;
-
- /// container for newly created objects, they'll be added in Sector::update
- GameObjects gameobjects_new;
-
- MusicType currentmusic;
-
- HSQOBJECT sector_table;
- /// sector scripts
- typedef std::vector<HSQOBJECT> ScriptList;
- ScriptList scripts;
-
- Color ambient_light;
-
-public: // TODO make this private again
- /// show collision rectangles of moving objects (for debugging)
- static bool show_collrects;
- static bool draw_solids_only;
-
- GameObjects gameobjects;
- MovingObjects moving_objects;
- SpawnPoints spawnpoints;
- Portables portables;
-
- std::string music;
- float gravity;
-
- // some special objects, where we need direct access
- // (try to avoid accessing them directly)
- Player* player;
- std::list<TileMap*> solid_tilemaps;
- Camera* camera;
- DisplayEffect* effect;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux - A Jump'n Run
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#ifndef SUPERTUX_SERIALIZABLE_H
-#define SUPERTUX_SERIALIZABLE_H
-
-namespace lisp { class Writer; }
-
-class Serializable
-{
-public:
- virtual ~Serializable()
- { }
-
- virtual void write(lisp::Writer& writer) = 0;
-};
-
-#endif /*SUPERTUX_SERIALIZABLE_H*/
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include <config.h>
-
-#include "shrinkfade.hpp"
-#include "main.hpp"
-#include "video/drawing_context.hpp"
-
-ShrinkFade::ShrinkFade(const Vector& dest, float fade_time)
- : dest(dest), fade_time(fade_time), accum_time(0)
-{
- speedleft = dest.x / fade_time;
- speedright = (SCREEN_WIDTH - dest.x) / fade_time;
- speedtop = dest.y / fade_time;
- speedbottom = (SCREEN_HEIGHT - dest.y) / fade_time;
-}
-
-ShrinkFade::~ShrinkFade()
-{
-}
-
-void
-ShrinkFade::update(float elapsed_time)
-{
- accum_time += elapsed_time;
- if(accum_time > fade_time)
- accum_time = fade_time;
-}
-
-void
-ShrinkFade::draw(DrawingContext& context)
-{
- float progress = accum_time / fade_time;
- context.draw_inverse_ellipse(dest,
- Vector(2*SCREEN_WIDTH * (1.0f - progress),
- 2*SCREEN_HEIGHT * (1.0f - progress)),
- Color(0, 0, 0), LAYER_GUI+1);
-}
-
-bool
-ShrinkFade::done()
-{
- return accum_time >= fade_time;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#ifndef __SHRINKFADE_HPP__
-#define __SHRINKFADE_HPP__
-
-#include "screen_fade.hpp"
-#include "math/vector.hpp"
-
-/**
- * Shrinks a rectangle screen towards a specific position
- */
-class ShrinkFade : public ScreenFade
-{
-public:
- ShrinkFade(const Vector& point, float fade_time);
- virtual ~ShrinkFade();
-
- virtual void update(float elapsed_time);
- virtual void draw(DrawingContext& context);
-
- virtual bool done();
-
-private:
- Vector dest;
- float fade_time;
- float accum_time;
- float speedleft, speedright, speedtop, speedbottom;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
-
-#include <stdexcept>
-#include <iostream>
-#include "spawn_point.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/list_iterator.hpp"
-#include "log.hpp"
-
-SpawnPoint::SpawnPoint()
-{}
-
-SpawnPoint::SpawnPoint(const SpawnPoint& other)
- : name(other.name), pos(other.pos)
-{}
-
-SpawnPoint::SpawnPoint(const lisp::Lisp* slisp)
-{
- pos.x = -1;
- pos.y = -1;
- lisp::ListIterator iter(slisp);
- while(iter.next()) {
- const std::string& token = iter.item();
- if(token == "name") {
- iter.value()->get(name);
- } else if(token == "x") {
- iter.value()->get(pos.x);
- } else if(token == "y") {
- iter.value()->get(pos.y);
- } else {
- log_warning << "unknown token '" << token << "' in SpawnPoint" << std::endl;
- }
- }
-
- if(name == "")
- throw std::runtime_error("No name specified for spawnpoint");
- if(pos.x < 0 || pos.y < 0)
- throw std::runtime_error("Invalid coordinates for spawnpoint");
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#ifndef __SPAWN_POINT_H__
-#define __SPAWN_POINT_H__
-
-#include <string>
-#include "math/vector.hpp"
-namespace lisp { class Lisp; }
-
-class SpawnPoint
-{
-public:
- SpawnPoint();
- SpawnPoint(const SpawnPoint& other);
- SpawnPoint(const lisp::Lisp* lisp);
-
- std::string name;
- Vector pos;
-};
-
-#endif
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <iostream>
#include <cmath>
-#include <cassert>
-#include <stdexcept>
-
-#include "video/surface.hpp"
-#include "sprite.hpp"
-#include "video/drawing_context.hpp"
-#include "log.hpp"
-#include "timer.hpp"
+#include "sprite/sprite.hpp"
+#include "supertux/timer.hpp"
Sprite::Sprite(SpriteData& newdata)
: data(newdata),
void
Sprite::draw_part(DrawingContext& context, const Vector& source,
- const Vector& size, const Vector& pos, int layer)
+ const Vector& size, const Vector& pos, int layer)
{
assert(action != 0);
update();
}
context.draw_surface_part(action->surfaces[frameidx], source, size,
- pos - Vector(action->x_offset, action->y_offset),
- layer + action->z_order);
+ pos - Vector(action->x_offset, action->y_offset),
+ layer + action->z_order);
}
int
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#ifndef SUPERTUX_SPRITE_H
-#define SUPERTUX_SPRITE_H
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <string>
-#include <assert.h>
+#ifndef HEADER_SUPERTUX_SPRITE_SPRITE_HPP
+#define HEADER_SUPERTUX_SPRITE_SPRITE_HPP
-#include "math/vector.hpp"
-#include "math/rect.hpp"
-#include "sprite_data.hpp"
-#include "video/color.hpp"
+#include "sprite/sprite_data.hpp"
#include "video/drawing_context.hpp"
class Surface;
void draw(DrawingContext& context, const Vector& pos, int layer);
void draw_part(DrawingContext& context, const Vector& source,
- const Vector& size, const Vector& pos, int layer);
+ const Vector& size, const Vector& pos, int layer);
/** Set action (or state) */
void set_action(const std::string& name, int loops = -1);
Blend blend;
SpriteData::Action* action;
+
+private:
+ Sprite& operator=(const Sprite&);
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <config.h>
+#include "sprite/sprite_data.hpp"
-#include <iostream>
-#include <cmath>
-#include <sstream>
#include <stdexcept>
+#include <sstream>
-#include "sprite_data.hpp"
-#include "resources.hpp"
-#include "video/drawing_context.hpp"
#include "lisp/list_iterator.hpp"
-#include "log.hpp"
+#include "util/log.hpp"
SpriteData::Action::Action()
{
if(!lisp->get("name", action->name)) {
if(!actions.empty())
throw std::runtime_error(
- "If there are more than one action, they need names!");
+ "If there are more than one action, they need names!");
}
std::vector<float> hitbox;
if (lisp->get("hitbox", hitbox)) {
Action* act_tmp = get_action(mirror_action);
if(act_tmp == NULL) {
throw std::runtime_error("Could not mirror action. Action not found\n"
- "Mirror actions must be defined after the real one!");
+ "Mirror actions must be defined after the real one!");
} else {
float max_w = 0;
float max_h = 0;
- for(int i = 0; static_cast<unsigned int>(i) < act_tmp->surfaces.size();
- i++) {
+ for(int i = 0; static_cast<unsigned int>(i) < act_tmp->surfaces.size(); i++) {
Surface* surface = new Surface(*(act_tmp->surfaces[i]));
surface->hflip();
max_w = std::max(max_w, (float) surface->get_width());
}
return i->second;
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef SUPERTUX_SPRITE_DATA_H
-#define SUPERTUX_SPRITE_DATA_H
+#ifndef HEADER_SUPERTUX_SPRITE_SPRITE_DATA_HPP
+#define HEADER_SUPERTUX_SPRITE_SPRITE_DATA_HPP
-#include <string>
-#include <vector>
#include <map>
#include "lisp/lisp.hpp"
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <iostream>
-#include <sstream>
-#include <stdexcept>
+#include "sprite/sprite_manager.hpp"
-#include "sprite_manager.hpp"
-#include "sprite_data.hpp"
-#include "sprite.hpp"
-#include "lisp/lisp.hpp"
#include "lisp/parser.hpp"
-#include "lisp/list_iterator.hpp"
-#include "file_system.hpp"
-#include "log.hpp"
+#include "sprite/sprite.hpp"
+#include "util/file_system.hpp"
SpriteManager* sprite_manager = NULL;
}
}
-Sprite*
+std::auto_ptr<Sprite>
SpriteManager::create(const std::string& name)
{
Sprites::iterator i = sprites.find(name);
data = i->second;
}
- return new Sprite(*data);
+ return std::auto_ptr<Sprite>(new Sprite(*data));
}
SpriteData*
}
std::auto_ptr<SpriteData> data (
- new SpriteData(sprite, FileSystem::dirname(filename)) );
+ new SpriteData(sprite, FileSystem::dirname(filename)) );
sprites[filename] = data.release();
return sprites[filename];
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef SUPERTUX_SPRITE_MANAGER_H
-#define SUPERTUX_SPRITE_MANAGER_H
+#ifndef HEADER_SUPERTUX_SPRITE_SPRITE_MANAGER_HPP
+#define HEADER_SUPERTUX_SPRITE_SPRITE_MANAGER_HPP
#include <map>
+#include <memory>
#include <string>
class SpriteData;
~SpriteManager();
/** loads a sprite. */
- Sprite* create(const std::string& filename);
+ std::auto_ptr<Sprite> create(const std::string& filename);
private:
SpriteData* load(const std::string& filename);
extern SpriteManager* sprite_manager;
#endif
+
+/* EOF */
+++ /dev/null
-#
-# SuperTux - squirrel library build script
-# Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-#
-# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-
-## Add include/ to include directories
-
-INCLUDE_DIRECTORIES(${SUPERTUX_SOURCE_DIR}/src/squirrel/include/)
-
-## build list of source files
-
-FILE(GLOB SQUIRREL_SOURCES squirrel/*.cpp sqstdlib/*.cpp sqstdlib/*.c)
-
-## add additional compiler switches
-
-ADD_DEFINITIONS(-include ${CMAKE_BINARY_DIR}/config.h)
-# the squirrel sources are out of our control so don't be too pedantic about
-# them
-REMOVE_DEFINITIONS(-Werror -W)
-
-## define a target for building the library
-
-ADD_LIBRARY(squirrel ${SQUIRREL_SOURCES})
+++ /dev/null
-Copyright (c) 2003-2009 Alberto Demichelis\r
-\r
-This software is provided 'as-is', without any \r
-express or implied warranty. In no event will the \r
-authors be held liable for any damages arising from \r
-the use of this software.\r
-\r
-Permission is granted to anyone to use this software \r
-for any purpose, including commercial applications, \r
-and to alter it and redistribute it freely, subject \r
-to the following restrictions:\r
-\r
- 1. The origin of this software must not be \r
- misrepresented; you must not claim that \r
- you wrote the original software. If you \r
- use this software in a product, an \r
- acknowledgment in the product \r
- documentation would be appreciated but is \r
- not required.\r
-\r
- 2. Altered source versions must be plainly \r
- marked as such, and must not be \r
- misrepresented as being the original \r
- software.\r
-\r
- 3. This notice may not be removed or \r
- altered from any source distribution.\r
------------------------------------------------------\r
-END OF COPYRIGHT
\ No newline at end of file
+++ /dev/null
-***version 2.2.3 stable***\r
--added sq_getfunctioninfo\r
--added compile time flag SQUSEDOUBLE to use double precision floats\r
--added global slot _floatsize_ int the base lib to recognize single precision and double precision builds\r
--sq_wakeupvm can now resume the vm with an exception\r
--added sqstd_format\r
--generators can now be instantiated by calling sq_call() or closure.call()\r
--fixed a bug in sqstd_printcallstack(thx takayuki_h)\r
--fixed modulo by zero(thx jup)\r
--fixed negative enums and constants\r
--fixed generator crash bug if invoked as tail call (thx Mr.Accident)\r
--fixed some minor bug\r
-\r
-***2008-09-24 ***\r
-***version 2.2.2 stable***\r
--fixed some behaviour inconsistencies in thread.call() and thread.wakeup() (thx Mr.Accident)\r
--fixed coroutine error propagation\r
--fixed lingering return value from native function (thx Tom Leonard)\r
--fixed a bug if array.sort() is given a bad sort function (thx Tom Leonard)\r
--fixed some minor api bug\r
--added sq_arrayremove() and sq_arrayinsert()\r
-\r
-***2008-05-16 ***\r
-***version 2.2.1 stable***\r
--fixed a tailcall bug\r
-\r
-***2008-02-17 ***\r
-***version 2.2 stable ***\r
--added _newslot metamethod in classes\r
--added enums added constants\r
--added sq_pushconsttable, sq_setconsttable\r
--added default param\r
--added octal literals(thx Dinosaur)\r
--fixed debug hook, 'calls' and 'returns' are properly notified in the same number.\r
--fixed a coroutine bug\r
-\r
-***2007-07-29 ***\r
-***version 2.1.2 stable***\r
--new behaviour for generators iteration using foreach\r
-now when a generator is iterated by foreach the value returned by a 'return val' statement\r
-will terminate the iteration but will not be returned as foreach iteration\r
--added sq_setclassudsize()\r
--added sq_clear()\r
--added table.clear(), array.clear()\r
--fixed sq_cmp() (thx jyuill)\r
--fixed minor bugs\r
-\r
-***2006-08-21 ***\r
-***version 2.1.1 stable***\r
--vm refactoring\r
--optimized internal function memory layout\r
--new global symbol _version_ (is the version string)\r
--code size optimization for float literals(on 32bits float builts)\r
--now the raw ref API(sq_addref etc...) is fully reentrant.\r
--fixed a bug in sq_getdelegate() now pushes null if the object doesn't have a delegate(thx MatzeB)\r
--improved C reference performances in NO_GARBAGE_COLLECTOR builds\r
--sq_getlocal() now enumerates also outer values.\r
--fixed regexp library for GCC users.\r
-\r
-***2006-03-19 ***\r
-***version 2.1 stable***\r
--added static class fields, new keyword static\r
--added 64bits architecture support\r
--added global slot _intsize_ int the base lib to recognize 32bits and 64bits builds\r
--added functions with fixed environment, closure.bindenv() built-in function\r
--all types except userdata and null implement the tostring() method\r
--string concatenation now invokes metamethod _tostring\r
--new metamethods for class objects _newmember and _inherited\r
--sq_call() sq_resume() sq_wakeupvm() have a new signature\r
--new C referencing implementation(scales more with the amount of references)\r
--refactored hash table\r
--new api functions sq_newslot(),sq_tobool(),sq_getbase(), sq_instanceof(), sq_bindenv()\r
--the api func sq_createslot was deprecated but still supported in form of C macro on top of sq_newslot\r
--sq_setreleasehook() now also works for classes\r
--stream.readstr() and stream.writestr() have been deprecated(this affects file and blob)\r
--fixed squirrel.h undeclared api calls\r
--fixed few minor bugs\r
--SQChar is now defined as wchar_t\r
--removed warning when building with -Wall -pedantic for GCC users\r
--added new std io function writeclosuretofile()\r
--added new std string functions strip(),rstrip(),lstrip() and split()\r
--regular expressions operators (+,*) now have more POSIX greedyness behaviour\r
--class constructors are now invoked as normal functions\r
-\r
-***2005-10-02 ***\r
-***version 2.0.5 stable***\r
--fixed some 64bits incompatibilities (thx sarge)\r
--fixed minor bug in the stdlib format() function (thx Rick)\r
--fixed a bug in dofile() that was preventing to compile empty files\r
--added new API sq_poptop() & sq_getfreevariable()\r
--some performance improvements\r
-\r
-***2005-08-14 ***\r
-***version 2.0.4 stable***\r
--weak references and related API calls\r
--added sq_objtobool()\r
--class instances memory policies improved(1 mem allocation for the whole instance)\r
--typetags are now declared as SQUserPointer instead of unsigned int\r
--first pass for 64bits compatibility\r
--fixed minor bug in the stdio stream\r
--fixed a bug in format()\r
--fixed bug in string.tointeger() and string.tofloat()\r
-\r
-***2005-06-24 ***\r
-***version 2.0.3 stable***\r
--dofile() and loadfile() in the iolib now can decode ASCII, UTF8 files UCS2 big-endian and little-endian\r
--sq_setparamscheck() : now typemesk can check for null\r
--added string escape sequence \xhhhh\r
--fixed some C++ standard incompatibilities\r
-\r
-***2005-05-15 ***\r
-***version 2.0.2 stable***\r
--performances improvements (expecially for GCC users)\r
--removed all dependencies from C++ exception handling\r
--various bugfixes\r
-\r
-***2005-04-12 ***\r
-***version 2.0.1 stable***\r
--various bugfixes\r
--sq_setparamscheck() now allows spaces in the typemask\r
-\r
-***2005-04-03 ***\r
-***version 2.0 stable***\r
--added API sq_gettypetag()\r
--added built-in function to the bool type(tointeger, tostring etc...)\r
-\r
-***2005-02-27 ***\r
-***version 2.0 release candidate 1(RC 1)***\r
--added API sq_reseterror()\r
--modified sq_release()\r
--now class instances can be cloned\r
--various bufixes\r
-\r
-***2005-01-26 ***\r
-***version 2.0 beta 1***\r
--added bool type\r
--class properties can be redefined in a derived class\r
--added ops *= /= and %=\r
--new syntax for class attributes declaration </ and /> instead of ( and )\r
--increased the max number of literals per function from 65535 to 16777215\r
--now free variables have proper lexical scoping\r
--added API sq_createinstance(), sq_pushbool(), sq_getbool()\r
--added built-in function type()\r
--added built-in function obj.rawin(key) in table,class and instance\r
--sq_rawget() and sq_rawset() now work also on classes and instances\r
--the VM no longer uses C++ exception handling (more suitable for embedded devices)\r
--various bufixes\r
-\r
-***2004-12-21 ***\r
-***version 2.0 alpha 2***\r
--globals scoping changed, now if :: is omitted the VM automatically falls back on the root table\r
--various bufixes\r
--added class level attributes\r
-\r
-***2004-12-12 ***\r
-***version 2.0 alpha 1***\r
--codebase branch from version 1.x\r
--added classes\r
--added functions with variable number of parameters(vargc & vargv and the ...)\r
--0 and 0.0 are now considered 'false' by all conditional statements(if,while,for,?,do-while)\r
--added new api functions sq_newclass() sq_setinstanceup() sq_getinstanceup() sq_getattributes() sq_setattributes()\r
--modified api sq_settypetag()\r
-\r
-***2004-11-01 ***\r
-***version 1.0 stable***\r
--fixed some minor bug\r
--improoved operator 'delete' performances\r
--added scientific notation for float numbers( eg. 2.e16 or 2.e-2)\r
-\r
-***2004-08-30 ***\r
-***version 1.0 release candidate 2(RC 2)***\r
--fixed bug in the vm(thx Pierre Renaux)\r
--fixed bug in the optimizer(thx Pierre Renaux)\r
--fixed some bug in the documentation(thx JD)\r
--added new api functions for raw object handling\r
--removed nested multiline comments\r
--reduced memory footprint in C references\r
-\r
-***2004-08-23 ***\r
-***version 1.0 release candidate 1(RC 1)***\r
--fixed division by zero\r
--the 'in' operator and obj.rawget() do not query the default delegate anymore\r
--added function sq_getprintfunc()\r
--added new standard library 'auxlib'(implements default error handlers)\r
-\r
-***2004-07-12 ***\r
-***version 1.0 beta 4***\r
--fixed a bug in the integer.tochar() built-in method\r
--fixed unary minus operator\r
--fixed bug in dofile()\r
--fixed inconsistency between != and == operators(on float/integer comparison)\r
--added javascript style unsigned right shift operator '>>>'\r
--added array(size) constructor built-in function\r
--array.resize(size,[fill]) built-in function accepts an optional 'fill' value\r
--improved debug API, added sq_getclosureinfo() and sq_setnativeclosurename()\r
-\r
-***2004-05-23 ***\r
-***version 1.0 beta 3***\r
--minor vm bug fixes\r
--string allocation is now faster\r
--tables and array memory usage is now less conservative(they shrink)\r
--added regular expression routines in the standard library\r
--The 'c' expression now accepts only 1 character(thx irbrian)\r
--multiline strings <[ ]> have been substituted with C# style verbatim strings (eg. @"string")\r
--added new keyword 'parent' for accessing the delegate of tables and unserdata\r
--The metamethod '_clone' has been renamed '_cloned'\r
--the _delslot metamethod's behaviour and prototype have been changed\r
--new default function in the integer and float object 'tochar()'\r
--the built-in function chcode2string has been removed\r
--the default method [table].getdelegate() has been removed\r
--new api sq_rawdeleteslot()\r
--new table built-in method rawdelete(key)\r
--the dynamic mudule loading has been removed from the standard distribution\r
--some optimizations in the VM\r
-\r
-***2004-04-21 ***\r
-***version 1.0 beta 2***\r
--minor compiler/parser bug fixes\r
--sq_newclosure has a different prototype, the "paramscheck" of paramter has been moved to the new function sq_setparamscheck()\r
--sq_setparamscheck allows to add automatic parameters type checking in native closures\r
--sq_compile() lost the lineinfo parameter\r
--new api sq_enabledebuginfo() globally sets compiler's debug info generation\r
--added consistency check on bytecode serialization\r
--fixed += operator, now works on strings like +\r
--added global slot in the base lib _charsize_ to recognize unicode builds from ascii builds runtime\r
--added registry table\r
--new api call sq_pushregistrytable()\r
--added type tag to the userdata type sq_settypetag()\r
--sq_getuserdata now queries the userdata typetag\r
--the built in function collect_garbage() as been renamed collectgarbage() for consistency reasons\r
--new standard libraries(sqlibs are now obsolete)\r
-\r
-***2004-02-20 ***\r
-***version 1.0 beta 1***\r
--fixed a bug in the compiler (thanks Martin Kofler)\r
--fixed bug in the switch case statement\r
--fixed the _unm metamethod\r
--fixed minor bugs in the API\r
--fixed automatic stack resizing\r
--first beta version \r
- first pass code clean up in the VM and base lib\r
- first pass code coverege test has been done on VM and built-in lib\r
--new VM creation API sq_open() sq_close() (sq_newvm and sq_releasevm are now obsolete)\r
--new api allows to specifiy a "print" function to output text(sq_printfunc)\r
--added some small optimizations\r
--new cooperative multi-threading capabilities in the base library(coroutines), VMs are now a built in type("thread")\r
--new built in functions have been added for manipulating the new "thread" type\r
--friend virtual machines share the same root table, error handler and debug hook by default\r
--new compile time options\r
-\r
-***2004-01-19 ***\r
-***version 0.9 alpha***\r
--fixed a garbage collection bug\r
--fixed some API bugs(thanks to Joshua Jensen)\r
--fixed tail calls (in the version 0.8 the tail call optimization was erroneously disabled)\r
--new function parameters semantic, now passing a wrong number of parameters generates an exception\r
--native closures have now a built in parameter number checking\r
--sq_rawget and sq_rawset now work also on arrays\r
--sq_getsize now woks also on userdata\r
--the userdata release hook prototype is changed(now passes the size of the userdata)\r
--the lexer reader function now returns an integer instead of a char that allows better error checking on the input(thx Joshua Jensen)\r
--faster compiler\r
--try/catch blocks do not cause any runtime memory allocation anymore\r
-\r
-***2003-12-06 ***\r
-***version 0.8 alpha***\r
--fixed a bug that was preventing to have callable userdata throught the metamethod _call\r
--fixed a garbage collection bug\r
--fixed == operator now can compare correctly different types\r
--new built in method getstackinfos(level)\r
--improoved line informations precision for the debug hook\r
--new api call sq_compilebuffer()\r
--new built-in api function compilestring()\r
--new syntactic sugar for function declarations inside tables\r
--the debug API has been finalized\r
-\r
-***2003-11-17 ***\r
-***version 0.7 alpha***\r
--fixed critical bug SQInteger the tail call system\r
--fixed bug in the continue statement code generation\r
--fixed func call param issue(thanks to Rewoonenco Andrew)\r
--added _delslot metamethod(thanks to Rewoonenco Andrew)\r
--new multiline string expression ( delimited by <[ and ]> )\r
--normal strings ("") do not allow embedded new line anymore\r
--reduced vm memory footprint(C refs are shared between friend VMs)\r
--new api method sq_deleteslot()\r
--new debug hook event 'r' is triggered when a function returns\r
-\r
-***2003-11-04 ***\r
-***version 0.6 alpha***\r
--fixed switch statement(was executing the default case after a break)\r
--sq_call() doesn't pop the closure (just the params)\r
--the vm execution can be suspended from the C API anytime (micro-threads)\r
--new api calls sq_suspendvm() sq_wakeupvm() sq_getvmstate() and sq_reservestack()\r
-\r
-***2003-10-13 ***\r
-***version 0.5 alpha***\r
--fixed some minor bug\r
--tested with non ASCII identifiers in unicode mode(I've tried chinese chars)\r
--added built-in function string.find()\r
--the built-in function array.sort() optionally accepts a cmp(a,b) function\r
--the debug hook function now has a new prototype debug_hook(event_type,sourcefile,line,functionname)\r
--fixed some debug info imprecision\r
-\r
-***2003-10-01 ***\r
-***version 0.4 alpha***\r
--faster VM\r
--sq_call will pop arguments and closure also in case of failure\r
--fixed a bug in sq_remove\r
--now the VM detects delegation cycles(and throws an exception)\r
--new operators ++ and --\r
--new operator ',' comma operator\r
--fixed some expression precedence issue\r
--fixed bug in sq_arraypop\r
-\r
-***2003-09-15 ***\r
-***version 0.3 alpha***\r
--fixed a bug in array::insert()\r
--optional Unicode core(define SQUNICODE or _UNICODE on Win32)\r
--sq_compiler uses a new reader function SQLEXREADFUNC\r
--the debug hook passes 'l' instead of 'line' for line callbacks\r
- and 'c' instead of 'call' for call callbacks\r
--new array.extend() bulit-in function\r
--new API sq_clone()\r
-\r
-***2003-09-10 ***\r
-***version 0.2 pre-alpha***\r
--new completely reentrant VM (sq_open and sq_close are now obsolete)\r
--sq_newvm() has a new prototype\r
--allocators are now global and linked in the VM\r
--_newslot meta method added\r
--rawset creates a slot if doesn't exists\r
--the compiler error callback pass the vm handle(thanks Pierre Renaux)\r
--sq_setforeignptr() sq_getforeingptr() are now public\r
--sq_resume() now is possible to resume generators from C\r
--sq_getlasterror() retrieve the last thrown error\r
--improved docs\r
-\r
-***2003-09-06 ***\r
-***version 0.1 pre-alpha***\r
-first release\r
+++ /dev/null
-The programming language SQUIRREL 2.2.3 stable\r
-\r
---------------------------------------------------\r
-The project has been compiled and run on Windows(Windows XP/2000 on Intel x86 Windows XP Pro on AMD x64) and\r
-Linux(Slackware 9.0 on Intel x86, Fedora Core 4 on AMD x64).\r
-\r
-Has been tested with the following compilers:\r
- MS Visual C++ 6.0,7.0,7.1 and 8.0 (32 and 64bits)\r
- MinGW gcc 3.2 (mingw special 20020817-1)\r
- Cygnus gcc 3.2\r
- Linux gcc 3.2.3\r
- Linux gcc 4.0.0 (x86 64bits)\r
- \r
-\r
-Feedback and suggestions are appreciated \r
-project page - http://www.squirrel-lang.org\r
-community forums - http://www.squirrel-lang.org/Forums\r
-wiki - http://wiki.squirrel-lang.org\r
-author - alberto@demichelis.net\r
-\r
-END OF README\r
-\r
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQSTD_AUXLIB_H_
-#define _SQSTD_AUXLIB_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-SQUIRREL_API void sqstd_seterrorhandlers(HSQUIRRELVM v);
-SQUIRREL_API void sqstd_printcallstack(HSQUIRRELVM v);
-
-#ifdef __cplusplus
-} /*extern "C"*/
-#endif
-
-#endif /* _SQSTD_AUXLIB_H_ */
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQSTDBLOB_H_
-#define _SQSTDBLOB_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-SQUIRREL_API SQUserPointer sqstd_createblob(HSQUIRRELVM v, SQInteger size);
-SQUIRREL_API SQRESULT sqstd_getblob(HSQUIRRELVM v,SQInteger idx,SQUserPointer *ptr);
-SQUIRREL_API SQInteger sqstd_getblobsize(HSQUIRRELVM v,SQInteger idx);
-
-SQUIRREL_API SQRESULT sqstd_register_bloblib(HSQUIRRELVM v);
-
-#ifdef __cplusplus
-} /*extern "C"*/
-#endif
-
-#endif /*_SQSTDBLOB_H_*/
-
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQSTDIO_H_
-#define _SQSTDIO_H_
-
-#ifdef __cplusplus
-
-#define SQSTD_STREAM_TYPE_TAG 0x80000000
-
-struct SQStream {
- virtual ~SQStream() {}
- virtual SQInteger Read(void *buffer, SQInteger size) = 0;
- virtual SQInteger Write(void *buffer, SQInteger size) = 0;
- virtual SQInteger Flush() = 0;
- virtual SQInteger Tell() = 0;
- virtual SQInteger Len() = 0;
- virtual SQInteger Seek(SQInteger offset, SQInteger origin) = 0;
- virtual bool IsValid() = 0;
- virtual bool EOS() = 0;
-};
-
-extern "C" {
-#endif
-
-#define SQ_SEEK_CUR 0
-#define SQ_SEEK_END 1
-#define SQ_SEEK_SET 2
-
-typedef void* SQFILE;
-
-SQUIRREL_API SQFILE sqstd_fopen(const SQChar *,const SQChar *);
-SQUIRREL_API SQInteger sqstd_fread(SQUserPointer, SQInteger, SQInteger, SQFILE);
-SQUIRREL_API SQInteger sqstd_fwrite(const SQUserPointer, SQInteger, SQInteger, SQFILE);
-SQUIRREL_API SQInteger sqstd_fseek(SQFILE , SQInteger , SQInteger);
-SQUIRREL_API SQInteger sqstd_ftell(SQFILE);
-SQUIRREL_API SQInteger sqstd_fflush(SQFILE);
-SQUIRREL_API SQInteger sqstd_fclose(SQFILE);
-SQUIRREL_API SQInteger sqstd_feof(SQFILE);
-
-SQUIRREL_API SQRESULT sqstd_createfile(HSQUIRRELVM v, SQFILE file,SQBool own);
-SQUIRREL_API SQRESULT sqstd_getfile(HSQUIRRELVM v, SQInteger idx, SQFILE *file);
-
-//compiler helpers
-SQUIRREL_API SQRESULT sqstd_loadfile(HSQUIRRELVM v,const SQChar *filename,SQBool printerror);
-SQUIRREL_API SQRESULT sqstd_dofile(HSQUIRRELVM v,const SQChar *filename,SQBool retval,SQBool printerror);
-SQUIRREL_API SQRESULT sqstd_writeclosuretofile(HSQUIRRELVM v,const SQChar *filename);
-
-SQUIRREL_API SQRESULT sqstd_register_iolib(HSQUIRRELVM v);
-
-#ifdef __cplusplus
-} /*extern "C"*/
-#endif
-
-#endif /*_SQSTDIO_H_*/
-
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQSTD_MATH_H_
-#define _SQSTD_MATH_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-SQUIRREL_API SQRESULT sqstd_register_mathlib(HSQUIRRELVM v);
-
-#ifdef __cplusplus
-} /*extern "C"*/
-#endif
-
-#endif /*_SQSTD_MATH_H_*/
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQSTD_STRING_H_
-#define _SQSTD_STRING_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef unsigned int SQRexBool;
-typedef struct SQRex SQRex;
-
-typedef struct {
- const SQChar *begin;
- SQInteger len;
-} SQRexMatch;
-
-SQUIRREL_API SQRex *sqstd_rex_compile(const SQChar *pattern,const SQChar **error);
-SQUIRREL_API void sqstd_rex_free(SQRex *exp);
-SQUIRREL_API SQBool sqstd_rex_match(SQRex* exp,const SQChar* text);
-SQUIRREL_API SQBool sqstd_rex_search(SQRex* exp,const SQChar* text, const SQChar** out_begin, const SQChar** out_end);
-SQUIRREL_API SQBool sqstd_rex_searchrange(SQRex* exp,const SQChar* text_begin,const SQChar* text_end,const SQChar** out_begin, const SQChar** out_end);
-SQUIRREL_API SQInteger sqstd_rex_getsubexpcount(SQRex* exp);
-SQUIRREL_API SQBool sqstd_rex_getsubexp(SQRex* exp, SQInteger n, SQRexMatch *subexp);
-
-SQUIRREL_API SQRESULT sqstd_format(HSQUIRRELVM v,SQInteger nformatstringidx,SQInteger *outlen,SQChar **output);
-
-SQUIRREL_API SQRESULT sqstd_register_stringlib(HSQUIRRELVM v);
-
-#ifdef __cplusplus
-} /*extern "C"*/
-#endif
-
-#endif /*_SQSTD_STRING_H_*/
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQSTD_SYSTEMLIB_H_
-#define _SQSTD_SYSTEMLIB_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-SQUIRREL_API SQInteger sqstd_register_systemlib(HSQUIRRELVM v);
-
-#ifdef __cplusplus
-} /*extern "C"*/
-#endif
-
-#endif /* _SQSTD_SYSTEMLIB_H_ */
+++ /dev/null
-/*
-Copyright (c) 2003-2009 Alberto Demichelis
-
-This software is provided 'as-is', without any
-express or implied warranty. In no event will the
-authors be held liable for any damages arising from
-the use of this software.
-
-Permission is granted to anyone to use this software
-for any purpose, including commercial applications,
-and to alter it and redistribute it freely, subject
-to the following restrictions:
-
- 1. The origin of this software must not be
- misrepresented; you must not claim that
- you wrote the original software. If you
- use this software in a product, an
- acknowledgment in the product
- documentation would be appreciated but is
- not required.
-
- 2. Altered source versions must be plainly
- marked as such, and must not be
- misrepresented as being the original
- software.
-
- 3. This notice may not be removed or
- altered from any source distribution.
-
-*/
-#ifndef _SQUIRREL_H_
-#define _SQUIRREL_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef SQUIRREL_API
-#define SQUIRREL_API extern
-#endif
-
-#if (defined(_WIN64) || defined(_LP64))
-#define _SQ64
-#endif
-
-#ifdef _SQ64
-#ifdef _MSC_VER
-typedef __int64 SQInteger;
-typedef unsigned __int64 SQUnsignedInteger;
-typedef unsigned __int64 SQHash; /*should be the same size of a pointer*/
-#else
-typedef long SQInteger;
-typedef unsigned long SQUnsignedInteger;
-typedef unsigned long SQHash; /*should be the same size of a pointer*/
-#endif
-typedef int SQInt32;
-#else
-typedef int SQInteger;
-typedef int SQInt32; /*must be 32 bits(also on 64bits processors)*/
-typedef unsigned int SQUnsignedInteger;
-typedef unsigned int SQHash; /*should be the same size of a pointer*/
-#endif
-
-
-#ifdef SQUSEDOUBLE
-typedef double SQFloat;
-#else
-typedef float SQFloat;
-#endif
-
-#if defined(SQUSEDOUBLE) && !defined(_SQ64)
-#ifdef _MSC_VER
-typedef __int64 SQRawObjectVal; //must be 64bits
-#else
-typedef long SQRawObjectVal; //must be 64bits
-#endif
-#define SQ_OBJECT_RAWINIT() { _unVal.raw = 0; }
-#else
-typedef SQUnsignedInteger SQRawObjectVal; //is 32 bits on 32 bits builds and 64 bits otherwise
-#define SQ_OBJECT_RAWINIT()
-#endif
-
-typedef void* SQUserPointer;
-typedef SQUnsignedInteger SQBool;
-typedef SQInteger SQRESULT;
-
-#define SQTrue (1)
-#define SQFalse (0)
-
-struct SQVM;
-struct SQTable;
-struct SQArray;
-struct SQString;
-struct SQClosure;
-struct SQGenerator;
-struct SQNativeClosure;
-struct SQUserData;
-struct SQFunctionProto;
-struct SQRefCounted;
-struct SQClass;
-struct SQInstance;
-struct SQDelegable;
-
-#ifdef _UNICODE
-#define SQUNICODE
-#endif
-
-#ifdef SQUNICODE
-#if (defined(_MSC_VER) && _MSC_VER >= 1400) // 1400 = VS8
-
-#if defined(wchar_t) //this is if the compiler considers wchar_t as native type
-#define wchar_t unsigned short
-#endif
-
-#else
-typedef unsigned short wchar_t;
-#endif
-
-typedef wchar_t SQChar;
-#define _SC(a) L##a
-#define scstrcmp wcscmp
-#define scsprintf swprintf
-#define scstrlen wcslen
-#define scstrtod wcstod
-#define scstrtol wcstol
-#define scatoi _wtoi
-#define scstrtoul wcstoul
-#define scvsprintf vswprintf
-#define scstrstr wcsstr
-#define scisspace iswspace
-#define scisdigit iswdigit
-#define scisxdigit iswxdigit
-#define scisalpha iswalpha
-#define sciscntrl iswcntrl
-#define scisalnum iswalnum
-#define scprintf wprintf
-#define MAX_CHAR 0xFFFF
-#else
-typedef char SQChar;
-#define _SC(a) a
-#define scstrcmp strcmp
-#define scsprintf sprintf
-#define scstrlen strlen
-#define scstrtod strtod
-#define scstrtol strtol
-#define scatoi atoi
-#define scstrtoul strtoul
-#define scvsprintf vsprintf
-#define scstrstr strstr
-#define scisspace isspace
-#define scisdigit isdigit
-#define scisxdigit isxdigit
-#define sciscntrl iscntrl
-#define scisalpha isalpha
-#define scisalnum isalnum
-#define scprintf printf
-#define MAX_CHAR 0xFF
-#endif
-
-#define SQUIRREL_VERSION _SC("Squirrel 2.2.3 stable")
-#define SQUIRREL_COPYRIGHT _SC("Copyright (C) 2003-2009 Alberto Demichelis")
-#define SQUIRREL_AUTHOR _SC("Alberto Demichelis")
-
-#define SQ_VMSTATE_IDLE 0
-#define SQ_VMSTATE_RUNNING 1
-#define SQ_VMSTATE_SUSPENDED 2
-
-#define SQUIRREL_EOB 0
-#define SQ_BYTECODE_STREAM_TAG 0xFAFA
-
-#define SQOBJECT_REF_COUNTED 0x08000000
-#define SQOBJECT_NUMERIC 0x04000000
-#define SQOBJECT_DELEGABLE 0x02000000
-#define SQOBJECT_CANBEFALSE 0x01000000
-
-#define SQ_MATCHTYPEMASKSTRING (-99999)
-
-#define _RT_MASK 0x00FFFFFF
-#define _RAW_TYPE(type) (type&_RT_MASK)
-
-#define _RT_NULL 0x00000001
-#define _RT_INTEGER 0x00000002
-#define _RT_FLOAT 0x00000004
-#define _RT_BOOL 0x00000008
-#define _RT_STRING 0x00000010
-#define _RT_TABLE 0x00000020
-#define _RT_ARRAY 0x00000040
-#define _RT_USERDATA 0x00000080
-#define _RT_CLOSURE 0x00000100
-#define _RT_NATIVECLOSURE 0x00000200
-#define _RT_GENERATOR 0x00000400
-#define _RT_USERPOINTER 0x00000800
-#define _RT_THREAD 0x00001000
-#define _RT_FUNCPROTO 0x00002000
-#define _RT_CLASS 0x00004000
-#define _RT_INSTANCE 0x00008000
-#define _RT_WEAKREF 0x00010000
-
-typedef enum tagSQObjectType{
- OT_NULL = (_RT_NULL|SQOBJECT_CANBEFALSE),
- OT_INTEGER = (_RT_INTEGER|SQOBJECT_NUMERIC|SQOBJECT_CANBEFALSE),
- OT_FLOAT = (_RT_FLOAT|SQOBJECT_NUMERIC|SQOBJECT_CANBEFALSE),
- OT_BOOL = (_RT_BOOL|SQOBJECT_CANBEFALSE),
- OT_STRING = (_RT_STRING|SQOBJECT_REF_COUNTED),
- OT_TABLE = (_RT_TABLE|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE),
- OT_ARRAY = (_RT_ARRAY|SQOBJECT_REF_COUNTED),
- OT_USERDATA = (_RT_USERDATA|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE),
- OT_CLOSURE = (_RT_CLOSURE|SQOBJECT_REF_COUNTED),
- OT_NATIVECLOSURE = (_RT_NATIVECLOSURE|SQOBJECT_REF_COUNTED),
- OT_GENERATOR = (_RT_GENERATOR|SQOBJECT_REF_COUNTED),
- OT_USERPOINTER = _RT_USERPOINTER,
- OT_THREAD = (_RT_THREAD|SQOBJECT_REF_COUNTED) ,
- OT_FUNCPROTO = (_RT_FUNCPROTO|SQOBJECT_REF_COUNTED), //internal usage only
- OT_CLASS = (_RT_CLASS|SQOBJECT_REF_COUNTED),
- OT_INSTANCE = (_RT_INSTANCE|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE),
- OT_WEAKREF = (_RT_WEAKREF|SQOBJECT_REF_COUNTED)
-}SQObjectType;
-
-#define ISREFCOUNTED(t) (t&SQOBJECT_REF_COUNTED)
-
-
-typedef union tagSQObjectValue
-{
- struct SQTable *pTable;
- struct SQArray *pArray;
- struct SQClosure *pClosure;
- struct SQGenerator *pGenerator;
- struct SQNativeClosure *pNativeClosure;
- struct SQString *pString;
- struct SQUserData *pUserData;
- SQInteger nInteger;
- SQFloat fFloat;
- SQUserPointer pUserPointer;
- struct SQFunctionProto *pFunctionProto;
- struct SQRefCounted *pRefCounted;
- struct SQDelegable *pDelegable;
- struct SQVM *pThread;
- struct SQClass *pClass;
- struct SQInstance *pInstance;
- struct SQWeakRef *pWeakRef;
- SQRawObjectVal raw;
-}SQObjectValue;
-
-
-typedef struct tagSQObject
-{
- SQObjectType _type;
- SQObjectValue _unVal;
-}SQObject;
-
-typedef struct tagSQStackInfos{
- const SQChar* funcname;
- const SQChar* source;
- SQInteger line;
-}SQStackInfos;
-
-typedef struct SQVM* HSQUIRRELVM;
-typedef SQObject HSQOBJECT;
-typedef SQInteger (*SQFUNCTION)(HSQUIRRELVM);
-typedef SQInteger (*SQRELEASEHOOK)(SQUserPointer,SQInteger size);
-typedef void (*SQCOMPILERERROR)(HSQUIRRELVM,const SQChar * /*desc*/,const SQChar * /*source*/,SQInteger /*line*/,SQInteger /*column*/);
-typedef void (*SQPRINTFUNCTION)(HSQUIRRELVM,const SQChar * ,...);
-
-typedef SQInteger (*SQWRITEFUNC)(SQUserPointer,SQUserPointer,SQInteger);
-typedef SQInteger (*SQREADFUNC)(SQUserPointer,SQUserPointer,SQInteger);
-
-typedef SQInteger (*SQLEXREADFUNC)(SQUserPointer);
-
-typedef struct tagSQRegFunction{
- const SQChar *name;
- SQFUNCTION f;
- SQInteger nparamscheck;
- const SQChar *typemask;
-}SQRegFunction;
-
-typedef struct tagSQFunctionInfo {
- SQUserPointer funcid;
- const SQChar *name;
- const SQChar *source;
-}SQFunctionInfo;
-
-
-/*vm*/
-SQUIRREL_API HSQUIRRELVM sq_open(SQInteger initialstacksize);
-SQUIRREL_API HSQUIRRELVM sq_newthread(HSQUIRRELVM friendvm, SQInteger initialstacksize);
-SQUIRREL_API void sq_seterrorhandler(HSQUIRRELVM v);
-SQUIRREL_API void sq_close(HSQUIRRELVM v);
-SQUIRREL_API void sq_setforeignptr(HSQUIRRELVM v,SQUserPointer p);
-SQUIRREL_API SQUserPointer sq_getforeignptr(HSQUIRRELVM v);
-SQUIRREL_API void sq_setprintfunc(HSQUIRRELVM v, SQPRINTFUNCTION printfunc);
-SQUIRREL_API SQPRINTFUNCTION sq_getprintfunc(HSQUIRRELVM v);
-SQUIRREL_API SQRESULT sq_suspendvm(HSQUIRRELVM v);
-SQUIRREL_API SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool resumedret,SQBool retval,SQBool raiseerror,SQBool throwerror);
-SQUIRREL_API SQInteger sq_getvmstate(HSQUIRRELVM v);
-
-/*compiler*/
-SQUIRREL_API SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQChar *sourcename,SQBool raiseerror);
-SQUIRREL_API SQRESULT sq_compilebuffer(HSQUIRRELVM v,const SQChar *s,SQInteger size,const SQChar *sourcename,SQBool raiseerror);
-SQUIRREL_API void sq_enabledebuginfo(HSQUIRRELVM v, SQBool enable);
-SQUIRREL_API void sq_notifyallexceptions(HSQUIRRELVM v, SQBool enable);
-SQUIRREL_API void sq_setcompilererrorhandler(HSQUIRRELVM v,SQCOMPILERERROR f);
-
-/*stack operations*/
-SQUIRREL_API void sq_push(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API void sq_pop(HSQUIRRELVM v,SQInteger nelemstopop);
-SQUIRREL_API void sq_poptop(HSQUIRRELVM v);
-SQUIRREL_API void sq_remove(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQInteger sq_gettop(HSQUIRRELVM v);
-SQUIRREL_API void sq_settop(HSQUIRRELVM v,SQInteger newtop);
-SQUIRREL_API void sq_reservestack(HSQUIRRELVM v,SQInteger nsize);
-SQUIRREL_API SQInteger sq_cmp(HSQUIRRELVM v);
-SQUIRREL_API void sq_move(HSQUIRRELVM dest,HSQUIRRELVM src,SQInteger idx);
-
-/*object creation handling*/
-SQUIRREL_API SQUserPointer sq_newuserdata(HSQUIRRELVM v,SQUnsignedInteger size);
-SQUIRREL_API void sq_newtable(HSQUIRRELVM v);
-SQUIRREL_API void sq_newarray(HSQUIRRELVM v,SQInteger size);
-SQUIRREL_API void sq_newclosure(HSQUIRRELVM v,SQFUNCTION func,SQUnsignedInteger nfreevars);
-SQUIRREL_API SQRESULT sq_setparamscheck(HSQUIRRELVM v,SQInteger nparamscheck,const SQChar *typemask);
-SQUIRREL_API SQRESULT sq_bindenv(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API void sq_pushstring(HSQUIRRELVM v,const SQChar *s,SQInteger len);
-SQUIRREL_API void sq_pushfloat(HSQUIRRELVM v,SQFloat f);
-SQUIRREL_API void sq_pushinteger(HSQUIRRELVM v,SQInteger n);
-SQUIRREL_API void sq_pushbool(HSQUIRRELVM v,SQBool b);
-SQUIRREL_API void sq_pushuserpointer(HSQUIRRELVM v,SQUserPointer p);
-SQUIRREL_API void sq_pushnull(HSQUIRRELVM v);
-SQUIRREL_API SQObjectType sq_gettype(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQInteger sq_getsize(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_getbase(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQBool sq_instanceof(HSQUIRRELVM v);
-SQUIRREL_API void sq_tostring(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API void sq_tobool(HSQUIRRELVM v, SQInteger idx, SQBool *b);
-SQUIRREL_API SQRESULT sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar **c);
-SQUIRREL_API SQRESULT sq_getinteger(HSQUIRRELVM v,SQInteger idx,SQInteger *i);
-SQUIRREL_API SQRESULT sq_getfloat(HSQUIRRELVM v,SQInteger idx,SQFloat *f);
-SQUIRREL_API SQRESULT sq_getbool(HSQUIRRELVM v,SQInteger idx,SQBool *b);
-SQUIRREL_API SQRESULT sq_getthread(HSQUIRRELVM v,SQInteger idx,HSQUIRRELVM *thread);
-SQUIRREL_API SQRESULT sq_getuserpointer(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p);
-SQUIRREL_API SQRESULT sq_getuserdata(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p,SQUserPointer *typetag);
-SQUIRREL_API SQRESULT sq_settypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer typetag);
-SQUIRREL_API SQRESULT sq_gettypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer *typetag);
-SQUIRREL_API void sq_setreleasehook(HSQUIRRELVM v,SQInteger idx,SQRELEASEHOOK hook);
-SQUIRREL_API SQChar *sq_getscratchpad(HSQUIRRELVM v,SQInteger minsize);
-SQUIRREL_API SQRESULT sq_getfunctioninfo(HSQUIRRELVM v,SQInteger idx,SQFunctionInfo *fi);
-SQUIRREL_API SQRESULT sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger *nparams,SQUnsignedInteger *nfreevars);
-SQUIRREL_API SQRESULT sq_setnativeclosurename(HSQUIRRELVM v,SQInteger idx,const SQChar *name);
-SQUIRREL_API SQRESULT sq_setinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer p);
-SQUIRREL_API SQRESULT sq_getinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p,SQUserPointer typetag);
-SQUIRREL_API SQRESULT sq_setclassudsize(HSQUIRRELVM v, SQInteger idx, SQInteger udsize);
-SQUIRREL_API SQRESULT sq_newclass(HSQUIRRELVM v,SQBool hasbase);
-SQUIRREL_API SQRESULT sq_createinstance(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_setattributes(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_getattributes(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_getclass(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API void sq_weakref(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_getdefaultdelegate(HSQUIRRELVM v,SQObjectType t);
-
-/*object manipulation*/
-SQUIRREL_API void sq_pushroottable(HSQUIRRELVM v);
-SQUIRREL_API void sq_pushregistrytable(HSQUIRRELVM v);
-SQUIRREL_API void sq_pushconsttable(HSQUIRRELVM v);
-SQUIRREL_API SQRESULT sq_setroottable(HSQUIRRELVM v);
-SQUIRREL_API SQRESULT sq_setconsttable(HSQUIRRELVM v);
-SQUIRREL_API SQRESULT sq_newslot(HSQUIRRELVM v, SQInteger idx, SQBool bstatic);
-SQUIRREL_API SQRESULT sq_deleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval);
-SQUIRREL_API SQRESULT sq_set(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_get(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_rawget(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_rawset(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_rawdeleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval);
-SQUIRREL_API SQRESULT sq_arrayappend(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_arraypop(HSQUIRRELVM v,SQInteger idx,SQBool pushval);
-SQUIRREL_API SQRESULT sq_arrayresize(HSQUIRRELVM v,SQInteger idx,SQInteger newsize);
-SQUIRREL_API SQRESULT sq_arrayreverse(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_arrayremove(HSQUIRRELVM v,SQInteger idx,SQInteger itemidx);
-SQUIRREL_API SQRESULT sq_arrayinsert(HSQUIRRELVM v,SQInteger idx,SQInteger destpos);
-SQUIRREL_API SQRESULT sq_setdelegate(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_getdelegate(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_clone(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_setfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval);
-SQUIRREL_API SQRESULT sq_next(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_getweakrefval(HSQUIRRELVM v,SQInteger idx);
-SQUIRREL_API SQRESULT sq_clear(HSQUIRRELVM v,SQInteger idx);
-
-/*calls*/
-SQUIRREL_API SQRESULT sq_call(HSQUIRRELVM v,SQInteger params,SQBool retval,SQBool raiseerror);
-SQUIRREL_API SQRESULT sq_resume(HSQUIRRELVM v,SQBool retval,SQBool raiseerror);
-SQUIRREL_API const SQChar *sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedInteger idx);
-SQUIRREL_API const SQChar *sq_getfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval);
-SQUIRREL_API SQRESULT sq_throwerror(HSQUIRRELVM v,const SQChar *err);
-SQUIRREL_API void sq_reseterror(HSQUIRRELVM v);
-SQUIRREL_API void sq_getlasterror(HSQUIRRELVM v);
-
-/*raw object handling*/
-SQUIRREL_API SQRESULT sq_getstackobj(HSQUIRRELVM v,SQInteger idx,HSQOBJECT *po);
-SQUIRREL_API void sq_pushobject(HSQUIRRELVM v,HSQOBJECT obj);
-SQUIRREL_API void sq_addref(HSQUIRRELVM v,HSQOBJECT *po);
-SQUIRREL_API SQBool sq_release(HSQUIRRELVM v,HSQOBJECT *po);
-SQUIRREL_API void sq_resetobject(HSQOBJECT *po);
-SQUIRREL_API const SQChar *sq_objtostring(HSQOBJECT *o);
-SQUIRREL_API SQBool sq_objtobool(HSQOBJECT *o);
-SQUIRREL_API SQInteger sq_objtointeger(HSQOBJECT *o);
-SQUIRREL_API SQFloat sq_objtofloat(HSQOBJECT *o);
-SQUIRREL_API SQRESULT sq_getobjtypetag(HSQOBJECT *o,SQUserPointer * typetag);
-
-/*GC*/
-SQUIRREL_API SQInteger sq_collectgarbage(HSQUIRRELVM v);
-
-/*serialization*/
-SQUIRREL_API SQRESULT sq_writeclosure(HSQUIRRELVM vm,SQWRITEFUNC writef,SQUserPointer up);
-SQUIRREL_API SQRESULT sq_readclosure(HSQUIRRELVM vm,SQREADFUNC readf,SQUserPointer up);
-
-/*mem allocation*/
-SQUIRREL_API void *sq_malloc(SQUnsignedInteger size);
-SQUIRREL_API void *sq_realloc(void* p,SQUnsignedInteger oldsize,SQUnsignedInteger newsize);
-SQUIRREL_API void sq_free(void *p,SQUnsignedInteger size);
-
-/*debug*/
-SQUIRREL_API SQRESULT sq_stackinfos(HSQUIRRELVM v,SQInteger level,SQStackInfos *si);
-SQUIRREL_API void sq_setdebughook(HSQUIRRELVM v);
-
-/*UTILITY MACRO*/
-#define sq_isnumeric(o) ((o)._type&SQOBJECT_NUMERIC)
-#define sq_istable(o) ((o)._type==OT_TABLE)
-#define sq_isarray(o) ((o)._type==OT_ARRAY)
-#define sq_isfunction(o) ((o)._type==OT_FUNCPROTO)
-#define sq_isclosure(o) ((o)._type==OT_CLOSURE)
-#define sq_isgenerator(o) ((o)._type==OT_GENERATOR)
-#define sq_isnativeclosure(o) ((o)._type==OT_NATIVECLOSURE)
-#define sq_isstring(o) ((o)._type==OT_STRING)
-#define sq_isinteger(o) ((o)._type==OT_INTEGER)
-#define sq_isfloat(o) ((o)._type==OT_FLOAT)
-#define sq_isuserpointer(o) ((o)._type==OT_USERPOINTER)
-#define sq_isuserdata(o) ((o)._type==OT_USERDATA)
-#define sq_isthread(o) ((o)._type==OT_THREAD)
-#define sq_isnull(o) ((o)._type==OT_NULL)
-#define sq_isclass(o) ((o)._type==OT_CLASS)
-#define sq_isinstance(o) ((o)._type==OT_INSTANCE)
-#define sq_isbool(o) ((o)._type==OT_BOOL)
-#define sq_isweakref(o) ((o)._type==OT_WEAKREF)
-#define sq_type(o) ((o)._type)
-
-/* deprecated */
-#define sq_createslot(v,n) sq_newslot(v,n,SQFalse)
-
-#define SQ_OK (0)
-#define SQ_ERROR (-1)
-
-#define SQ_FAILED(res) (res<0)
-#define SQ_SUCCEEDED(res) (res>=0)
-
-#ifdef __cplusplus
-} /*extern "C"*/
-#endif
-
-#endif /*_SQUIRREL_H_*/
+++ /dev/null
-static const SQChar serialize_state_nut[] = {
-0x74, 0x72, 0x79, 0x20, 0x7b, 0x0d, 0x0a, 0x09, 0x0d, 0x0a, 0x6c, 0x6f,
-0x63, 0x61, 0x6c, 0x20, 0x6f, 0x62, 0x6a, 0x73, 0x5f, 0x72, 0x65, 0x67,
-0x3d, 0x7b, 0x6d, 0x61, 0x78, 0x69, 0x64, 0x3d, 0x30, 0x2c, 0x72, 0x65,
-0x66, 0x73, 0x3d, 0x7b, 0x7d, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x63, 0x6f,
-0x6d, 0x70, 0x6c, 0x65, 0x78, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x20,
-0x3c, 0x2d, 0x20, 0x7b, 0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x74, 0x61, 0x62,
-0x6c, 0x65, 0x22, 0x5d, 0x20, 0x3d, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x2c,
-0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x61, 0x72, 0x72, 0x61, 0x79, 0x22, 0x5d,
-0x20, 0x3d, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x0d, 0x0a, 0x09, 0x5b,
-0x22, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x22, 0x5d, 0x20, 0x3d, 0x20, 0x6e,
-0x75, 0x6c, 0x6c, 0x2c, 0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x69, 0x6e, 0x73,
-0x74, 0x61, 0x6e, 0x63, 0x65, 0x22, 0x5d, 0x20, 0x3d, 0x20, 0x6e, 0x75,
-0x6c, 0x6c, 0x2c, 0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x77, 0x65, 0x61, 0x6b,
-0x72, 0x65, 0x66, 0x22, 0x5d, 0x20, 0x3d, 0x20, 0x6e, 0x75, 0x6c, 0x6c,
-0x2c, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x66, 0x75, 0x6e, 0x63,
-0x74, 0x69, 0x6f, 0x6e, 0x20, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x72,
-0x65, 0x66, 0x73, 0x28, 0x74, 0x29, 0x3a, 0x28, 0x6f, 0x62, 0x6a, 0x73,
-0x5f, 0x72, 0x65, 0x67, 0x29, 0x0d, 0x0a, 0x7b, 0x0d, 0x0a, 0x09, 0x69,
-0x66, 0x28, 0x74, 0x20, 0x3d, 0x3d, 0x20, 0x3a, 0x3a, 0x67, 0x65, 0x74,
-0x72, 0x6f, 0x6f, 0x74, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x29, 0x29,
-0x0d, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3b, 0x0d,
-0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6f, 0x74, 0x79, 0x70,
-0x65, 0x20, 0x3d, 0x20, 0x3a, 0x3a, 0x74, 0x79, 0x70, 0x65, 0x28, 0x74,
-0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x69, 0x66, 0x28, 0x6f, 0x74, 0x79, 0x70,
-0x65, 0x20, 0x69, 0x6e, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x78,
-0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x29, 0x0d, 0x0a, 0x09, 0x7b, 0x0d,
-0x0a, 0x09, 0x09, 0x69, 0x66, 0x28, 0x21, 0x28, 0x74, 0x20, 0x69, 0x6e,
-0x20, 0x6f, 0x62, 0x6a, 0x73, 0x5f, 0x72, 0x65, 0x67, 0x2e, 0x72, 0x65,
-0x66, 0x73, 0x29, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x6f,
-0x62, 0x6a, 0x73, 0x5f, 0x72, 0x65, 0x67, 0x2e, 0x72, 0x65, 0x66, 0x73,
-0x5b, 0x74, 0x5d, 0x20, 0x3c, 0x2d, 0x20, 0x6f, 0x62, 0x6a, 0x73, 0x5f,
-0x72, 0x65, 0x67, 0x2e, 0x6d, 0x61, 0x78, 0x69, 0x64, 0x2b, 0x2b, 0x3b,
-0x0d, 0x0a, 0x09, 0x09, 0x0d, 0x0a, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20,
-0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x65, 0x6f, 0x62, 0x6a, 0x65, 0x63,
-0x74, 0x28, 0x74, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
-0x28, 0x6f, 0x2c, 0x69, 0x2c, 0x76, 0x61, 0x6c, 0x29, 0x3a, 0x28, 0x6f,
-0x62, 0x6a, 0x73, 0x5f, 0x72, 0x65, 0x67, 0x29, 0x0d, 0x0a, 0x09, 0x09,
-0x20, 0x20, 0x20, 0x20, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x20, 0x20,
-0x20, 0x20, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x72, 0x65, 0x66, 0x73,
-0x28, 0x76, 0x61, 0x6c, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x20,
-0x20, 0x20, 0x20, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x72, 0x65, 0x66,
-0x73, 0x28, 0x69, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x20, 0x20, 0x20,
-0x20, 0x7d, 0x29, 0x0d, 0x0a, 0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x09,
-0x0d, 0x0a, 0x09, 0x7d, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x66,
-0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x67, 0x65, 0x74, 0x76,
-0x61, 0x6c, 0x75, 0x65, 0x28, 0x76, 0x29, 0x3a, 0x28, 0x6f, 0x62, 0x6a,
-0x73, 0x5f, 0x72, 0x65, 0x67, 0x29, 0x0d, 0x0a, 0x7b, 0x0d, 0x0a, 0x09,
-0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x28, 0x3a, 0x3a, 0x74, 0x79, 0x70,
-0x65, 0x28, 0x76, 0x29, 0x29, 0x0d, 0x0a, 0x09, 0x7b, 0x0d, 0x0a, 0x09,
-0x09, 0x63, 0x61, 0x73, 0x65, 0x20, 0x22, 0x74, 0x61, 0x62, 0x6c, 0x65,
-0x22, 0x3a, 0x0d, 0x0a, 0x09, 0x09, 0x63, 0x61, 0x73, 0x65, 0x20, 0x22,
-0x61, 0x72, 0x72, 0x61, 0x79, 0x22, 0x3a, 0x0d, 0x0a, 0x09, 0x09, 0x63,
-0x61, 0x73, 0x65, 0x20, 0x22, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x22, 0x3a,
-0x0d, 0x0a, 0x09, 0x09, 0x63, 0x61, 0x73, 0x65, 0x20, 0x22, 0x69, 0x6e,
-0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x22, 0x3a, 0x0d, 0x0a, 0x09, 0x09,
-0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x62, 0x6a, 0x73,
-0x5f, 0x72, 0x65, 0x67, 0x2e, 0x72, 0x65, 0x66, 0x73, 0x5b, 0x76, 0x5d,
-0x2e, 0x74, 0x6f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x29, 0x3b,
-0x0d, 0x0a, 0x09, 0x09, 0x63, 0x61, 0x73, 0x65, 0x20, 0x22, 0x69, 0x6e,
-0x74, 0x65, 0x67, 0x65, 0x72, 0x22, 0x3a, 0x0d, 0x0a, 0x09, 0x09, 0x63,
-0x61, 0x73, 0x65, 0x20, 0x22, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x22, 0x3a,
-0x0d, 0x0a, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75,
-0x72, 0x6e, 0x20, 0x76, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x63, 0x61, 0x73,
-0x65, 0x20, 0x22, 0x62, 0x6f, 0x6f, 0x6c, 0x22, 0x3a, 0x0d, 0x0a, 0x09,
-0x09, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20,
-0x76, 0x2e, 0x74, 0x6f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x29,
-0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x63, 0x61, 0x73, 0x65, 0x20, 0x22, 0x73,
-0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x3a, 0x0d, 0x0a, 0x09, 0x09, 0x09,
-0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, 0x3b, 0x0d, 0x0a, 0x09,
-0x09, 0x63, 0x61, 0x73, 0x65, 0x20, 0x22, 0x6e, 0x75, 0x6c, 0x6c, 0x22,
-0x3a, 0x0d, 0x0a, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74,
-0x75, 0x72, 0x6e, 0x20, 0x22, 0x6e, 0x75, 0x6c, 0x6c, 0x22, 0x3b, 0x0d,
-0x0a, 0x09, 0x09, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x0d,
-0x0a, 0x09, 0x09, 0x09, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x72, 0x65, 0x74,
-0x75, 0x72, 0x6e, 0x20, 0x70, 0x61, 0x63, 0x6b, 0x5f, 0x74, 0x79, 0x70,
-0x65, 0x28, 0x3a, 0x3a, 0x74, 0x79, 0x70, 0x65, 0x28, 0x76, 0x29, 0x29,
-0x3b, 0x0d, 0x0a, 0x09, 0x7d, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a,
-0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x64,
-0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x3d, 0x7b, 0x0d, 0x0a, 0x09, 0x5b,
-0x22, 0x6e, 0x75, 0x6c, 0x6c, 0x22, 0x5d, 0x3d, 0x22, 0x6e, 0x22, 0x2c,
-0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22,
-0x5d, 0x3d, 0x22, 0x73, 0x22, 0x2c, 0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x69,
-0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x22, 0x5d, 0x3d, 0x22, 0x69, 0x22,
-0x2c, 0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x22,
-0x5d, 0x3d, 0x22, 0x66, 0x22, 0x2c, 0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x75,
-0x73, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x22, 0x5d, 0x3d, 0x22, 0x75,
-0x22, 0x2c, 0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x66, 0x75, 0x6e, 0x63, 0x74,
-0x69, 0x6f, 0x6e, 0x22, 0x5d, 0x3d, 0x22, 0x66, 0x6e, 0x22, 0x2c, 0x0d,
-0x0a, 0x09, 0x5b, 0x22, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x5d, 0x3d,
-0x22, 0x74, 0x22, 0x2c, 0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x61, 0x72, 0x72,
-0x61, 0x79, 0x22, 0x5d, 0x3d, 0x22, 0x61, 0x22, 0x2c, 0x0d, 0x0a, 0x09,
-0x5b, 0x22, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x22,
-0x5d, 0x3d, 0x22, 0x67, 0x22, 0x2c, 0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x74,
-0x68, 0x72, 0x65, 0x61, 0x64, 0x22, 0x5d, 0x3d, 0x22, 0x68, 0x22, 0x2c,
-0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63,
-0x65, 0x22, 0x5d, 0x3d, 0x22, 0x78, 0x22, 0x2c, 0x20, 0x0d, 0x0a, 0x09,
-0x5b, 0x22, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x22, 0x5d, 0x3d, 0x22, 0x79,
-0x22, 0x2c, 0x20, 0x20, 0x0d, 0x0a, 0x09, 0x5b, 0x22, 0x62, 0x6f, 0x6f,
-0x6c, 0x22, 0x5d, 0x3d, 0x22, 0x62, 0x22, 0x2c, 0x0d, 0x0a, 0x09, 0x5b,
-0x22, 0x77, 0x65, 0x61, 0x6b, 0x72, 0x65, 0x66, 0x22, 0x5d, 0x3d, 0x22,
-0x77, 0x22, 0x20, 0x20, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x66,
-0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x63, 0x6b,
-0x5f, 0x74, 0x79, 0x70, 0x65, 0x28, 0x74, 0x79, 0x70, 0x65, 0x29, 0x3a,
-0x28, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x5f, 0x74, 0x79, 0x70, 0x65,
-0x73, 0x29, 0x0d, 0x0a, 0x7b, 0x0d, 0x0a, 0x09, 0x69, 0x66, 0x28, 0x74,
-0x79, 0x70, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x70, 0x61, 0x63, 0x6b, 0x65,
-0x64, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x29, 0x72, 0x65, 0x74, 0x75,
-0x72, 0x6e, 0x20, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x5f, 0x74, 0x79,
-0x70, 0x65, 0x73, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x5d, 0x0d, 0x0a, 0x09,
-0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x79, 0x70, 0x65, 0x0d,
-0x0a, 0x7d, 0x20, 0x0d, 0x0a, 0x0d, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74,
-0x69, 0x6f, 0x6e, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x65, 0x6f,
-0x62, 0x6a, 0x65, 0x63, 0x74, 0x28, 0x6f, 0x62, 0x6a, 0x2c, 0x66, 0x75,
-0x6e, 0x63, 0x29, 0x0d, 0x0a, 0x7b, 0x0d, 0x0a, 0x09, 0x6c, 0x6f, 0x63,
-0x61, 0x6c, 0x20, 0x74, 0x79, 0x20, 0x3d, 0x20, 0x3a, 0x3a, 0x74, 0x79,
-0x70, 0x65, 0x28, 0x6f, 0x62, 0x6a, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x69,
-0x66, 0x28, 0x74, 0x79, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x69, 0x6e, 0x73,
-0x74, 0x61, 0x6e, 0x63, 0x65, 0x22, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x09,
-0x09, 0x74, 0x72, 0x79, 0x20, 0x7b, 0x20, 0x2f, 0x2f, 0x54, 0x52, 0x59,
-0x20, 0x54, 0x4f, 0x20, 0x55, 0x53, 0x45, 0x20, 0x5f, 0x6e, 0x65, 0x78,
-0x74, 0x69, 0x0d, 0x0a, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6f,
-0x72, 0x65, 0x61, 0x63, 0x68, 0x28, 0x69, 0x64, 0x78, 0x2c, 0x76, 0x61,
-0x6c, 0x20, 0x69, 0x6e, 0x20, 0x6f, 0x62, 0x6a, 0x29, 0x0d, 0x0a, 0x09,
-0x09, 0x20, 0x20, 0x20, 0x20, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09,
-0x66, 0x75, 0x6e, 0x63, 0x28, 0x6f, 0x62, 0x6a, 0x2c, 0x69, 0x64, 0x78,
-0x2c, 0x76, 0x61, 0x6c, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x20, 0x20,
-0x20, 0x20, 0x7d, 0x0d, 0x0a, 0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x09,
-0x63, 0x61, 0x74, 0x63, 0x68, 0x28, 0x65, 0x29, 0x20, 0x7b, 0x0d, 0x0a,
-0x09, 0x09, 0x20, 0x20, 0x20, 0x66, 0x6f, 0x72, 0x65, 0x61, 0x63, 0x68,
-0x28, 0x69, 0x64, 0x78, 0x2c, 0x76, 0x61, 0x6c, 0x20, 0x69, 0x6e, 0x20,
-0x6f, 0x62, 0x6a, 0x2e, 0x67, 0x65, 0x74, 0x63, 0x6c, 0x61, 0x73, 0x73,
-0x28, 0x29, 0x29, 0x0d, 0x0a, 0x09, 0x09, 0x20, 0x20, 0x20, 0x7b, 0x0d,
-0x0a, 0x09, 0x09, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x28, 0x6f, 0x62, 0x6a,
-0x2c, 0x69, 0x64, 0x78, 0x2c, 0x6f, 0x62, 0x6a, 0x5b, 0x69, 0x64, 0x78,
-0x5d, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x20, 0x20, 0x20, 0x7d, 0x0d,
-0x0a, 0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x65,
-0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x74, 0x79, 0x20, 0x3d, 0x3d,
-0x20, 0x22, 0x77, 0x65, 0x61, 0x6b, 0x72, 0x65, 0x66, 0x22, 0x29, 0x20,
-0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x28, 0x6f, 0x62,
-0x6a, 0x2c, 0x22, 0x40, 0x72, 0x65, 0x66, 0x22, 0x2c, 0x6f, 0x62, 0x6a,
-0x2e, 0x72, 0x65, 0x66, 0x28, 0x29, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x7d,
-0x0d, 0x0a, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, 0x0d, 0x0a, 0x09,
-0x09, 0x66, 0x6f, 0x72, 0x65, 0x61, 0x63, 0x68, 0x28, 0x69, 0x64, 0x78,
-0x2c, 0x76, 0x61, 0x6c, 0x20, 0x69, 0x6e, 0x20, 0x6f, 0x62, 0x6a, 0x29,
-0x0d, 0x0a, 0x09, 0x09, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x20, 0x20, 0x20,
-0x20, 0x66, 0x75, 0x6e, 0x63, 0x28, 0x6f, 0x62, 0x6a, 0x2c, 0x69, 0x64,
-0x78, 0x2c, 0x76, 0x61, 0x6c, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x7d,
-0x0d, 0x0a, 0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x0d, 0x0a, 0x7d,
-0x0d, 0x0a, 0x0d, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
-0x20, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x74, 0x72, 0x65, 0x65, 0x28,
-0x29, 0x3a, 0x28, 0x6f, 0x62, 0x6a, 0x73, 0x5f, 0x72, 0x65, 0x67, 0x29,
-0x0d, 0x0a, 0x7b, 0x0d, 0x0a, 0x09, 0x66, 0x6f, 0x72, 0x65, 0x61, 0x63,
-0x68, 0x28, 0x69, 0x2c, 0x6f, 0x20, 0x69, 0x6e, 0x20, 0x6f, 0x62, 0x6a,
-0x73, 0x5f, 0x72, 0x65, 0x67, 0x2e, 0x72, 0x65, 0x66, 0x73, 0x29, 0x0d,
-0x0a, 0x09, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x62, 0x65, 0x67, 0x69, 0x6e,
-0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x28, 0x22, 0x6f, 0x22, 0x29,
-0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75,
-0x74, 0x65, 0x28, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x2c, 0x28, 0x69,
-0x3d, 0x3d, 0x3a, 0x3a, 0x67, 0x65, 0x74, 0x72, 0x6f, 0x6f, 0x74, 0x74,
-0x61, 0x62, 0x6c, 0x65, 0x28, 0x29, 0x3f, 0x22, 0x72, 0x22, 0x3a, 0x70,
-0x61, 0x63, 0x6b, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x28, 0x3a, 0x3a, 0x74,
-0x79, 0x70, 0x65, 0x28, 0x69, 0x29, 0x29, 0x29, 0x29, 0x3b, 0x0d, 0x0a,
-0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x5f, 0x74, 0x79, 0x70,
-0x65, 0x6f, 0x66, 0x20, 0x3d, 0x20, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66,
-0x20, 0x69, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x28, 0x5f, 0x74,
-0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x21, 0x3d, 0x20, 0x3a, 0x3a, 0x74,
-0x79, 0x70, 0x65, 0x28, 0x69, 0x29, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x09,
-0x09, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28,
-0x22, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x22, 0x2c, 0x5f, 0x74, 0x79,
-0x70, 0x65, 0x6f, 0x66, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x7d, 0x0d,
-0x0a, 0x09, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65,
-0x28, 0x22, 0x72, 0x65, 0x66, 0x22, 0x2c, 0x6f, 0x2e, 0x74, 0x6f, 0x73,
-0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x29, 0x29, 0x3b, 0x0d, 0x0a, 0x09,
-0x09, 0x69, 0x66, 0x28, 0x69, 0x20, 0x21, 0x3d, 0x20, 0x3a, 0x3a, 0x67,
-0x65, 0x74, 0x72, 0x6f, 0x6f, 0x74, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x28,
-0x29, 0x29, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x69, 0x74, 0x65, 0x72,
-0x61, 0x74, 0x65, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x28, 0x69, 0x2c,
-0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x6f, 0x62,
-0x6a, 0x2c, 0x69, 0x64, 0x78, 0x2c, 0x76, 0x61, 0x6c, 0x29, 0x20, 0x7b,
-0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x28, 0x3a, 0x3a, 0x74,
-0x79, 0x70, 0x65, 0x28, 0x76, 0x61, 0x6c, 0x29, 0x20, 0x3d, 0x3d, 0x20,
-0x22, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x29, 0x0d,
-0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e,
-0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0d, 0x0a, 0x09, 0x09,
-0x09, 0x09, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x65, 0x6c, 0x65, 0x6d, 0x65,
-0x6e, 0x74, 0x28, 0x22, 0x65, 0x22, 0x29, 0x3b, 0x09, 0x0d, 0x0a, 0x09,
-0x09, 0x09, 0x09, 0x09, 0x65, 0x6d, 0x69, 0x74, 0x76, 0x61, 0x6c, 0x75,
-0x65, 0x28, 0x22, 0x6b, 0x74, 0x22, 0x2c, 0x22, 0x6b, 0x76, 0x22, 0x2c,
-0x69, 0x64, 0x78, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09,
-0x65, 0x6d, 0x69, 0x74, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x28, 0x22, 0x76,
-0x74, 0x22, 0x2c, 0x22, 0x76, 0x22, 0x2c, 0x6f, 0x62, 0x6a, 0x5b, 0x69,
-0x64, 0x78, 0x5d, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x65,
-0x6e, 0x64, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x28, 0x22, 0x65,
-0x22, 0x29, 0x3b, 0x09, 0x0d, 0x0a, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x7d,
-0x29, 0x0d, 0x0a, 0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x09, 0x65, 0x6e,
-0x64, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x28, 0x22, 0x6f, 0x22,
-0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x7d, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d,
-0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x76,
-0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x5f, 0x77, 0x61, 0x74, 0x63, 0x68,
-0x28, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x73, 0x2c, 0x69, 0x64, 0x2c, 0x65,
-0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x29, 0x0d, 0x0a,
-0x7b, 0x0d, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75,
-0x6e, 0x63, 0x5f, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x72, 0x65, 0x74, 0x75,
-0x72, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20,
-0x28, 0x22, 0x0d, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70,
-0x61, 0x72, 0x61, 0x6d, 0x73, 0x3d, 0x5b, 0x5d, 0x3b, 0x0d, 0x0a, 0x09,
-0x0d, 0x0a, 0x09, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x2e, 0x61, 0x70,
-0x70, 0x65, 0x6e, 0x64, 0x28, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x73, 0x5b,
-0x22, 0x74, 0x68, 0x69, 0x73, 0x22, 0x5d, 0x29, 0x0d, 0x0a, 0x09, 0x6c,
-0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x3d, 0x31,
-0x3b, 0x0d, 0x0a, 0x09, 0x66, 0x6f, 0x72, 0x65, 0x61, 0x63, 0x68, 0x28,
-0x69, 0x2c, 0x76, 0x20, 0x69, 0x6e, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c,
-0x73, 0x29, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x28, 0x69, 0x21,
-0x3d, 0x22, 0x74, 0x68, 0x69, 0x73, 0x22, 0x20, 0x26, 0x26, 0x20, 0x69,
-0x5b, 0x30, 0x5d, 0x20, 0x21, 0x3d, 0x20, 0x27, 0x40, 0x27, 0x29, 0x7b,
-0x20, 0x2f, 0x2f, 0x66, 0x6f, 0x72, 0x65, 0x61, 0x63, 0x68, 0x20, 0x69,
-0x74, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x20, 0x73, 0x74, 0x61,
-0x72, 0x74, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x40, 0x0d, 0x0a, 0x09,
-0x09, 0x09, 0x69, 0x66, 0x28, 0x21, 0x66, 0x69, 0x72, 0x73, 0x74, 0x29,
-0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x5f,
-0x73, 0x72, 0x63, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x5f, 0x73, 0x72, 0x63,
-0x2b, 0x22, 0x2c, 0x22, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x0d, 0x0a,
-0x09, 0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x66, 0x69, 0x72,
-0x73, 0x74, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x0d, 0x0a, 0x09, 0x09, 0x09,
-0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e,
-0x64, 0x28, 0x76, 0x29, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x66, 0x75, 0x6e,
-0x63, 0x5f, 0x73, 0x72, 0x63, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x5f, 0x73,
-0x72, 0x63, 0x2b, 0x69, 0x0d, 0x0a, 0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09,
-0x7d, 0x0d, 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x5f, 0x73, 0x72, 0x63,
-0x3d, 0x66, 0x75, 0x6e, 0x63, 0x5f, 0x73, 0x72, 0x63, 0x2b, 0x22, 0x29,
-0x7b, 0x5c, 0x6e, 0x22, 0x0d, 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x5f,
-0x73, 0x72, 0x63, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x5f, 0x73, 0x72, 0x63,
-0x2b, 0x22, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x28, 0x22, 0x2b,
-0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2b, 0x22,
-0x29, 0x5c, 0x6e, 0x7d, 0x22, 0x0d, 0x0a, 0x09, 0x0d, 0x0a, 0x09, 0x74,
-0x72, 0x79, 0x20, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61,
-0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x3d, 0x3a, 0x3a, 0x63, 0x6f, 0x6d,
-0x70, 0x69, 0x6c, 0x65, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x66,
-0x75, 0x6e, 0x63, 0x5f, 0x73, 0x72, 0x63, 0x29, 0x3b, 0x0d, 0x0a, 0x09,
-0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x7b, 0x73, 0x74, 0x61,
-0x74, 0x75, 0x73, 0x3d, 0x22, 0x6f, 0x6b, 0x22, 0x20, 0x2c, 0x20, 0x76,
-0x61, 0x6c, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x28, 0x29, 0x2e, 0x61, 0x63,
-0x61, 0x6c, 0x6c, 0x28, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x29, 0x7d,
-0x3b, 0x0d, 0x0a, 0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x63, 0x61, 0x74, 0x63,
-0x68, 0x28, 0x65, 0x29, 0x0d, 0x0a, 0x09, 0x7b, 0x0d, 0x0a, 0x09, 0x09,
-0x0d, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x7b,
-0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3d, 0x22, 0x65, 0x72, 0x72, 0x6f,
-0x72, 0x22, 0x7d, 0x0d, 0x0a, 0x09, 0x7d, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a,
-0x0d, 0x0a, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x0d, 0x0a, 0x2f, 0x2f, 0x2f,
-0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-0x2f, 0x2f, 0x0d, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
-0x20, 0x65, 0x6d, 0x69, 0x74, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x28, 0x74,
-0x79, 0x70, 0x65, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x2c, 0x76,
-0x61, 0x6c, 0x75, 0x65, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x2c,
-0x76, 0x61, 0x6c, 0x29, 0x0d, 0x0a, 0x7b, 0x0d, 0x0a, 0x09, 0x61, 0x74,
-0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x74, 0x79, 0x70, 0x65,
-0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x2c, 0x70, 0x61, 0x63, 0x6b,
-0x5f, 0x74, 0x79, 0x70, 0x65, 0x28, 0x3a, 0x3a, 0x74, 0x79, 0x70, 0x65,
-0x28, 0x76, 0x61, 0x6c, 0x29, 0x29, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x61,
-0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x76, 0x61, 0x6c,
-0x75, 0x65, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x2c, 0x67, 0x65,
-0x74, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x28, 0x76, 0x61, 0x6c, 0x29, 0x2e,
-0x74, 0x6f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x29, 0x29, 0x3b,
-0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c,
-0x20, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x3d, 0x5b, 0x5d, 0x0d, 0x0a, 0x6c,
-0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x3d, 0x33,
-0x3b, 0x0d, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x73, 0x69, 0x3b,
-0x0d, 0x0a, 0x0d, 0x0a, 0x2f, 0x2f, 0x74, 0x72, 0x79, 0x20, 0x7b, 0x0d,
-0x0a, 0x09, 0x2f, 0x2f, 0x45, 0x4e, 0x55, 0x4d, 0x45, 0x52, 0x41, 0x54,
-0x45, 0x20, 0x54, 0x48, 0x45, 0x20, 0x53, 0x54, 0x41, 0x43, 0x4b, 0x20,
-0x57, 0x41, 0x54, 0x43, 0x48, 0x45, 0x53, 0x0d, 0x0a, 0x09, 0x77, 0x68,
-0x69, 0x6c, 0x65, 0x28, 0x73, 0x69, 0x3d, 0x3a, 0x3a, 0x67, 0x65, 0x74,
-0x73, 0x74, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x66, 0x6f, 0x73, 0x28, 0x6c,
-0x65, 0x76, 0x65, 0x6c, 0x29, 0x29, 0x0d, 0x0a, 0x09, 0x7b, 0x0d, 0x0a,
-0x09, 0x09, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x61, 0x70, 0x70, 0x65,
-0x6e, 0x64, 0x28, 0x73, 0x69, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x6c,
-0x65, 0x76, 0x65, 0x6c, 0x2b, 0x2b, 0x3b, 0x0d, 0x0a, 0x09, 0x7d, 0x0d,
-0x0a, 0x0d, 0x0a, 0x09, 0x2f, 0x2f, 0x45, 0x56, 0x41, 0x4c, 0x55, 0x41,
-0x54, 0x45, 0x20, 0x41, 0x4c, 0x4c, 0x20, 0x57, 0x41, 0x54, 0x43, 0x48,
-0x45, 0x53, 0x0d, 0x0a, 0x09, 0x6f, 0x62, 0x6a, 0x73, 0x5f, 0x72, 0x65,
-0x67, 0x2e, 0x72, 0x65, 0x66, 0x73, 0x5b, 0x3a, 0x3a, 0x67, 0x65, 0x74,
-0x72, 0x6f, 0x6f, 0x74, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x29, 0x5d,
-0x20, 0x3c, 0x2d, 0x20, 0x6f, 0x62, 0x6a, 0x73, 0x5f, 0x72, 0x65, 0x67,
-0x2e, 0x6d, 0x61, 0x78, 0x69, 0x64, 0x2b, 0x2b, 0x3b, 0x0d, 0x0a, 0x09,
-0x66, 0x6f, 0x72, 0x65, 0x61, 0x63, 0x68, 0x28, 0x69, 0x2c, 0x76, 0x61,
-0x6c, 0x20, 0x69, 0x6e, 0x20, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x29, 0x0d,
-0x0a, 0x09, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x28, 0x76, 0x61,
-0x6c, 0x2e, 0x73, 0x72, 0x63, 0x21, 0x3d, 0x22, 0x4e, 0x41, 0x54, 0x49,
-0x56, 0x45, 0x22, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x69,
-0x66, 0x28, 0x22, 0x77, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x22, 0x20,
-0x69, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x29, 0x20, 0x7b, 0x0d, 0x0a,
-0x09, 0x09, 0x09, 0x09, 0x76, 0x61, 0x6c, 0x2e, 0x77, 0x61, 0x74, 0x63,
-0x68, 0x65, 0x73, 0x20, 0x3c, 0x2d, 0x20, 0x7b, 0x7d, 0x0d, 0x0a, 0x09,
-0x09, 0x09, 0x09, 0x66, 0x6f, 0x72, 0x65, 0x61, 0x63, 0x68, 0x28, 0x69,
-0x2c, 0x77, 0x61, 0x74, 0x63, 0x68, 0x20, 0x69, 0x6e, 0x20, 0x77, 0x61,
-0x74, 0x63, 0x68, 0x65, 0x73, 0x29, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09,
-0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x28, 0x76,
-0x61, 0x6c, 0x2e, 0x73, 0x72, 0x63, 0x21, 0x3d, 0x22, 0x4e, 0x41, 0x54,
-0x49, 0x56, 0x45, 0x22, 0x29, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09,
-0x09, 0x09, 0x76, 0x61, 0x6c, 0x2e, 0x77, 0x61, 0x74, 0x63, 0x68, 0x65,
-0x73, 0x5b, 0x69, 0x5d, 0x20, 0x3c, 0x2d, 0x20, 0x65, 0x76, 0x61, 0x6c,
-0x75, 0x61, 0x74, 0x65, 0x5f, 0x77, 0x61, 0x74, 0x63, 0x68, 0x28, 0x76,
-0x61, 0x6c, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x73, 0x2c, 0x69, 0x2c,
-0x77, 0x61, 0x74, 0x63, 0x68, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09,
-0x09, 0x09, 0x09, 0x69, 0x66, 0x28, 0x76, 0x61, 0x6c, 0x2e, 0x77, 0x61,
-0x74, 0x63, 0x68, 0x65, 0x73, 0x5b, 0x69, 0x5d, 0x2e, 0x73, 0x74, 0x61,
-0x74, 0x75, 0x73, 0x21, 0x3d, 0x22, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22,
-0x29, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x62, 0x75,
-0x69, 0x6c, 0x64, 0x5f, 0x72, 0x65, 0x66, 0x73, 0x28, 0x76, 0x61, 0x6c,
-0x2e, 0x77, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x5b, 0x69, 0x5d, 0x2e,
-0x76, 0x61, 0x6c, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09,
-0x7d, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x65, 0x6c, 0x73, 0x65,
-0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x76, 0x61, 0x6c,
-0x2e, 0x77, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x5b, 0x69, 0x5d, 0x20,
-0x3c, 0x2d, 0x20, 0x7b, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3d, 0x22,
-0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x7d, 0x0d, 0x0a, 0x09, 0x09, 0x09,
-0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x76, 0x61,
-0x6c, 0x2e, 0x77, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x5b, 0x69, 0x5d,
-0x2e, 0x65, 0x78, 0x70, 0x20, 0x3c, 0x2d, 0x20, 0x77, 0x61, 0x74, 0x63,
-0x68, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09,
-0x09, 0x09, 0x09, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09,
-0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x09, 0x66, 0x6f, 0x72, 0x65, 0x61, 0x63,
-0x68, 0x28, 0x69, 0x2c, 0x6c, 0x20, 0x69, 0x6e, 0x20, 0x76, 0x61, 0x6c,
-0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x73, 0x29, 0x0d, 0x0a, 0x09, 0x09,
-0x09, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x72, 0x65, 0x66, 0x73, 0x28,
-0x6c, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x0d,
-0x0a, 0x09, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x65, 0x6c, 0x65, 0x6d, 0x65,
-0x6e, 0x74, 0x28, 0x22, 0x6f, 0x62, 0x6a, 0x73, 0x22, 0x29, 0x3b, 0x0d,
-0x0a, 0x09, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x74, 0x72, 0x65, 0x65,
-0x28, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x65, 0x6c, 0x65,
-0x6d, 0x65, 0x6e, 0x74, 0x28, 0x22, 0x6f, 0x62, 0x6a, 0x73, 0x22, 0x29,
-0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x09, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x65,
-0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x28, 0x22, 0x63, 0x61, 0x6c, 0x6c,
-0x73, 0x22, 0x29, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x09, 0x66, 0x6f, 0x72,
-0x65, 0x61, 0x63, 0x68, 0x28, 0x69, 0x2c, 0x76, 0x61, 0x6c, 0x20, 0x69,
-0x6e, 0x20, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x29, 0x0d, 0x0a, 0x09, 0x7b,
-0x0d, 0x0a, 0x0d, 0x0a, 0x09, 0x09, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x65,
-0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x28, 0x22, 0x63, 0x61, 0x6c, 0x6c,
-0x22, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69,
-0x62, 0x75, 0x74, 0x65, 0x28, 0x22, 0x66, 0x6e, 0x63, 0x22, 0x2c, 0x76,
-0x61, 0x6c, 0x2e, 0x66, 0x75, 0x6e, 0x63, 0x29, 0x3b, 0x0d, 0x0a, 0x09,
-0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x22,
-0x73, 0x72, 0x63, 0x22, 0x2c, 0x76, 0x61, 0x6c, 0x2e, 0x73, 0x72, 0x63,
-0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62,
-0x75, 0x74, 0x65, 0x28, 0x22, 0x6c, 0x69, 0x6e, 0x65, 0x22, 0x2c, 0x76,
-0x61, 0x6c, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x74, 0x6f, 0x73, 0x74,
-0x72, 0x69, 0x6e, 0x67, 0x28, 0x29, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09,
-0x66, 0x6f, 0x72, 0x65, 0x61, 0x63, 0x68, 0x28, 0x69, 0x2c, 0x76, 0x20,
-0x69, 0x6e, 0x20, 0x76, 0x61, 0x6c, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c,
-0x73, 0x29, 0x0d, 0x0a, 0x09, 0x09, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09,
-0x62, 0x65, 0x67, 0x69, 0x6e, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74,
-0x28, 0x22, 0x6c, 0x22, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09,
-0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x22, 0x6e,
-0x61, 0x6d, 0x65, 0x22, 0x2c, 0x67, 0x65, 0x74, 0x76, 0x61, 0x6c, 0x75,
-0x65, 0x28, 0x69, 0x29, 0x2e, 0x74, 0x6f, 0x73, 0x74, 0x72, 0x69, 0x6e,
-0x67, 0x28, 0x29, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x65,
-0x6d, 0x69, 0x74, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x28, 0x22, 0x74, 0x79,
-0x70, 0x65, 0x22, 0x2c, 0x22, 0x76, 0x61, 0x6c, 0x22, 0x2c, 0x76, 0x29,
-0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x65, 0x6c, 0x65,
-0x6d, 0x65, 0x6e, 0x74, 0x28, 0x22, 0x6c, 0x22, 0x29, 0x3b, 0x0d, 0x0a,
-0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x28, 0x22, 0x77,
-0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x22, 0x20, 0x69, 0x6e, 0x20, 0x76,
-0x61, 0x6c, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x66, 0x6f,
-0x72, 0x65, 0x61, 0x63, 0x68, 0x28, 0x69, 0x2c, 0x76, 0x20, 0x69, 0x6e,
-0x20, 0x76, 0x61, 0x6c, 0x2e, 0x77, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73,
-0x29, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09,
-0x09, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e,
-0x74, 0x28, 0x22, 0x77, 0x22, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09,
-0x09, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28,
-0x22, 0x69, 0x64, 0x22, 0x2c, 0x69, 0x2e, 0x74, 0x6f, 0x73, 0x74, 0x72,
-0x69, 0x6e, 0x67, 0x28, 0x29, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09,
-0x09, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28,
-0x22, 0x65, 0x78, 0x70, 0x22, 0x2c, 0x76, 0x2e, 0x65, 0x78, 0x70, 0x29,
-0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x61, 0x74, 0x74, 0x72,
-0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x22, 0x73, 0x74, 0x61, 0x74, 0x75,
-0x73, 0x22, 0x2c, 0x76, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x29,
-0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x28, 0x76,
-0x2e, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x21, 0x3d, 0x22, 0x65, 0x72,
-0x72, 0x6f, 0x72, 0x22, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x09, 0x09, 0x09,
-0x09, 0x09, 0x09, 0x65, 0x6d, 0x69, 0x74, 0x76, 0x61, 0x6c, 0x75, 0x65,
-0x28, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x2c, 0x22, 0x76, 0x61, 0x6c,
-0x22, 0x2c, 0x76, 0x2e, 0x76, 0x61, 0x6c, 0x29, 0x3b, 0x0d, 0x0a, 0x09,
-0x09, 0x09, 0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x65,
-0x6e, 0x64, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x28, 0x22, 0x77,
-0x22, 0x29, 0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x09, 0x7d, 0x0d, 0x0a, 0x09,
-0x09, 0x7d, 0x0d, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x65, 0x6c, 0x65,
-0x6d, 0x65, 0x6e, 0x74, 0x28, 0x22, 0x63, 0x61, 0x6c, 0x6c, 0x22, 0x29,
-0x3b, 0x0d, 0x0a, 0x09, 0x09, 0x20, 0x0d, 0x0a, 0x09, 0x7d, 0x0d, 0x0a,
-0x09, 0x65, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x28,
-0x22, 0x63, 0x61, 0x6c, 0x6c, 0x73, 0x22, 0x29, 0x3b, 0x0d, 0x0a, 0x0d,
-0x0a, 0x0d, 0x0a, 0x09, 0x6f, 0x62, 0x6a, 0x73, 0x5f, 0x72, 0x65, 0x67,
-0x20, 0x3d, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x3b, 0x0d, 0x0a, 0x09, 0x73,
-0x74, 0x61, 0x63, 0x6b, 0x20, 0x3d, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x3b,
-0x0d, 0x0a, 0x09, 0x0d, 0x0a, 0x09, 0x69, 0x66, 0x28, 0x22, 0x63, 0x6f,
-0x6c, 0x6c, 0x65, 0x63, 0x74, 0x67, 0x61, 0x72, 0x62, 0x61, 0x67, 0x65,
-0x22, 0x20, 0x69, 0x6e, 0x20, 0x3a, 0x3a, 0x67, 0x65, 0x74, 0x72, 0x6f,
-0x6f, 0x74, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x29, 0x29, 0x20, 0x3a,
-0x3a, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x67, 0x61, 0x72, 0x62,
-0x61, 0x67, 0x65, 0x28, 0x29, 0x3b, 0x0d, 0x0a, 0x7d, 0x63, 0x61, 0x74,
-0x63, 0x68, 0x28, 0x65, 0x29, 0x0d, 0x0a, 0x7b, 0x0d, 0x0a, 0x09, 0x3a,
-0x3a, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x22, 0x45, 0x52, 0x52, 0x4f,
-0x52, 0x22, 0x2b, 0x65, 0x2b, 0x22, 0x5c, 0x6e, 0x22, 0x29, 0x3b, 0x0d,
-0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x00,
-};
+++ /dev/null
-#include <squirrel.h>
-#include <assert.h>
-#include <sqstdblob.h>
-#include "sqrdbg.h"
-#include "sqdbgserver.h"
-
-
-#ifndef _UNICODE
-#define scstrcpy strcpy
-#else
-#define scstrcpy wcscpy
-#endif
-struct XMLEscape{
- const SQChar c;
- const SQChar *esc;
-};
-
-#define SQDBG_DEBUG_HOOK _SC("_sqdbg_debug_hook_")
-#define SQDBG_ERROR_HANDLER _SC("_sqdbg_error_handler_")
-
-XMLEscape g_escapes[]={
- {_SC('<'),_SC("<")},{'>',_SC(">")},{_SC('&'),_SC("&")},{_SC('\''),_SC("'")},{_SC('\"'),_SC(""")},{_SC('\n'),_SC(""n")},{_SC('\r'),_SC(""r")},{0, NULL}
-};
-
-const SQChar *IntToString(int n)
-{
- static SQChar temp[256];
- scsprintf(temp,_SC("%d"),n);
- return temp;
-}
-
-SQInteger debug_hook(HSQUIRRELVM v);
-SQInteger error_handler(HSQUIRRELVM v);
-
-SQInteger beginelement(HSQUIRRELVM v)
-{
- SQUserPointer up;
- const SQChar *name;
- sq_getuserpointer(v,-1,&up);
- SQDbgServer *self = (SQDbgServer*)up;
- sq_getuserpointer(v,-1,&up);
- sq_getstring(v,2,&name);
- self->BeginElement(name);
- return 0;
-}
-
-SQInteger endelement(HSQUIRRELVM v)
-{
- SQUserPointer up;
- const SQChar *name;
- sq_getuserpointer(v,-1,&up);
- SQDbgServer *self = (SQDbgServer*)up;
- sq_getuserpointer(v,-1,&up);
- sq_getstring(v,2,&name);
- self->EndElement(name);
- return 0;
-}
-
-SQInteger attribute(HSQUIRRELVM v)
-{
- SQUserPointer up;
- const SQChar *name,*value;
- sq_getuserpointer(v,-1,&up);
- SQDbgServer *self = (SQDbgServer*)up;
- sq_getuserpointer(v,-1,&up);
- sq_getstring(v,2,&name);
- sq_getstring(v,3,&value);
- self->Attribute(name,value);
- return 0;
-}
-
-const SQChar *EscapeXMLString(HSQUIRRELVM v,const SQChar *s)
-{
-
- SQChar *temp=sq_getscratchpad(v,((int)scstrlen(s)*6) + sizeof(SQChar));
- SQChar *dest=temp;
- while(*s!=_SC('\0')){
- int i=0;
- bool escaped=false;
- while(g_escapes[i].esc!=NULL){
- if(*s==g_escapes[i].c){
- scstrcpy(dest,g_escapes[i].esc);
- dest+=scstrlen(g_escapes[i].esc);
- escaped=true;
- break;
- }
- i++;
- }
- if(!escaped){*dest=*s;*dest++;}
- *s++;
- }
- *dest=_SC('\0');
- return temp;
-}
-
-SQDbgServer::SQDbgServer(HSQUIRRELVM v)
-{
- _ready = false;
- _nestedcalls = 0;
- _autoupdate = false;
- _v = v;
- _state = eDBG_Running;
- _accept = INVALID_SOCKET;
- _endpoint = INVALID_SOCKET;
- _maxrecursion = 10;
- sq_resetobject(&_debugroot);
-}
-
-SQDbgServer::~SQDbgServer()
-{
- sq_release(_v,&_debugroot);
- if(_accept != INVALID_SOCKET)
- sqdbg_closesocket(_accept);
- if(_endpoint != INVALID_SOCKET)
- sqdbg_closesocket(_endpoint);
-}
-
-bool SQDbgServer::Init()
-{
- //creates an environment table for the debugger
-
- sq_newtable(_v);
- sq_getstackobj(_v,-1,&_debugroot);
- sq_addref(_v,&_debugroot);
-
- //creates a emptyslot to store the watches
- sq_pushstring(_v,_SC("watches"),-1);
- sq_pushnull(_v);
- sq_createslot(_v,-3);
-
- sq_pushstring(_v,_SC("beginelement"),-1);
- sq_pushuserpointer(_v,this);
- sq_newclosure(_v,beginelement,1);
- sq_setparamscheck(_v,2,_SC(".s"));
- sq_createslot(_v,-3);
-
- sq_pushstring(_v,_SC("endelement"),-1);
- sq_pushuserpointer(_v,this);
- sq_newclosure(_v,endelement,1);
- sq_setparamscheck(_v,2,_SC(".s"));
- sq_createslot(_v,-3);
-
- sq_pushstring(_v,_SC("attribute"),-1);
- sq_pushuserpointer(_v,this);
- sq_newclosure(_v,attribute,1);
- sq_setparamscheck(_v,3,_SC(".ss"));
- sq_createslot(_v,-3);
-
- sq_pop(_v,1);
-
- //stores debug hook and error handler in the registry
- sq_pushregistrytable(_v);
-
- sq_pushstring(_v,SQDBG_DEBUG_HOOK,-1);
- sq_pushuserpointer(_v,this);
- sq_newclosure(_v,debug_hook,1);
- sq_createslot(_v,-3);
-
- sq_pushstring(_v,SQDBG_ERROR_HANDLER,-1);
- sq_pushuserpointer(_v,this);
- sq_newclosure(_v,error_handler,1);
- sq_createslot(_v,-3);
-
-
- sq_pop(_v,1);
-
- //sets the error handlers
- SetErrorHandlers();
- return true;
-}
-
-bool SQDbgServer::ReadMsg()
-{
- return false;
-}
-
-void SQDbgServer::BusyWait()
-{
- while( !ReadMsg() )
- sleep(0);
-}
-
-void SQDbgServer::SendChunk(const SQChar *chunk)
-{
- char *buf=NULL;
- int buf_len=0;
-#ifdef _UNICODE
- buf_len=(int)scstrlen(chunk)+1;
- buf=(char *)sq_getscratchpad(_v,(buf_len)*3);
- wcstombs((char *)buf,chunk,buf_len);
-#else
- buf_len=(int)scstrlen(chunk);
- buf=(char *)chunk;
-#endif
- send(_endpoint,(const char*)buf,(int)strlen((const char *)buf),0);
-}
-
-
-void SQDbgServer::Terminated()
-{
- BeginElement(_SC("terminated"));
- EndElement(_SC("terminated"));
- ::usleep(200);
-}
-
-void SQDbgServer::Hook(int type,int line,const SQChar *src,const SQChar *func)
-{
- switch(_state){
- case eDBG_Running:
- if(type==_SC('l') && _breakpoints.size()) {
- BreakPointSetItor itr = _breakpoints.find(BreakPoint(line,src));
- if(itr != _breakpoints.end()) {
- Break(line,src,_SC("breakpoint"));
- BreakExecution();
- }
- }
- break;
- case eDBG_Suspended:
- _nestedcalls=0;
- case eDBG_StepOver:
- switch(type){
- case _SC('l'):
- if(_nestedcalls==0) {
- Break(line,src,_SC("step"));
- BreakExecution();
- }
- break;
- case _SC('c'):
- _nestedcalls++;
- break;
- case _SC('r'):
- if(_nestedcalls==0){
- _nestedcalls=0;
-
- }else{
- _nestedcalls--;
- }
- break;
- }
- break;
- case eDBG_StepInto:
- switch(type){
- case _SC('l'):
- _nestedcalls=0;
- Break(line,src,_SC("step"));
- BreakExecution();
- break;
-
- }
- break;
- case eDBG_StepReturn:
- switch(type){
- case _SC('l'):
- break;
- case _SC('c'):
- _nestedcalls++;
- break;
- case _SC('r'):
- if(_nestedcalls==0){
- _nestedcalls=0;
- _state=eDBG_StepOver;
- }else{
- _nestedcalls--;
- }
-
- break;
- }
- break;
- case eDBG_Disabled:
- break;
- }
-}
-
-
-#define MSG_ID(x,y) ((y<<8)|x)
-//ab Add Breakpoint
-//rb Remove Breakpoint
-//sp Suspend
-void SQDbgServer::ParseMsg(const char *msg)
-{
-
- switch(*((unsigned short *)msg)){
- case MSG_ID('a','b'): {
- BreakPoint bp;
- if(ParseBreakpoint(msg+3,bp)){
- AddBreakpoint(bp);
- scprintf(_SC("added bp %d %s\n"),bp._line,bp._src.c_str());
- }
- else
- scprintf(_SC("error parsing add breakpoint"));
- }
- break;
- case MSG_ID('r','b'): {
- BreakPoint bp;
- if(ParseBreakpoint(msg+3,bp)){
- RemoveBreakpoint(bp);
- scprintf(_SC("removed bp %d %s\n"),bp._line,bp._src.c_str());
- }else
- scprintf(_SC("error parsing remove breakpoint"));
- }
- break;
- case MSG_ID('g','o'):
- if(_state!=eDBG_Running){
- _state=eDBG_Running;
- BeginDocument();
- BeginElement(_SC("resumed"));
- EndElement(_SC("resumed"));
- EndDocument();
-// Send(_SC("<resumed/>\r\n"));
- scprintf(_SC("go (execution resumed)\n"));
- }
- break;
- case MSG_ID('s','p'):
- if(_state!=eDBG_Suspended){
- _state=eDBG_Suspended;
- scprintf(_SC("suspend\n"));
- }
- break;
- case MSG_ID('s','o'):
- if(_state==eDBG_Suspended){
- _state=eDBG_StepOver;
- }
- break;
- case MSG_ID('s','i'):
- if(_state==eDBG_Suspended){
- _state=eDBG_StepInto;
- scprintf(_SC("step into\n"));
- }
- break;
- case MSG_ID('s','r'):
- if(_state==eDBG_Suspended){
- _state=eDBG_StepReturn;
- scprintf(_SC("step return\n"));
- }
- break;
- case MSG_ID('d','i'):
- if(_state!=eDBG_Disabled){
- _state=eDBG_Disabled;
- scprintf(_SC("disabled\n"));
- }
- break;
- case MSG_ID('a','w'): {
- Watch w;
- if(ParseWatch(msg+3,w))
- {
- AddWatch(w);
- scprintf(_SC("added watch %d %s\n"),w._id,w._exp.c_str());
- }
- else
- scprintf(_SC("error parsing add watch"));
- }
- break;
- case MSG_ID('r','w'): {
- int id;
- if(ParseRemoveWatch(msg+3,id))
- {
- RemoveWatch(id);
- scprintf(_SC("added watch %d\n"),id);
- }
- else
- scprintf(_SC("error parsing remove watch"));
- }
- break;
- case MSG_ID('t','r'):
- scprintf(_SC("terminate from user\n"));
- break;
- case MSG_ID('r','d'):
- scprintf(_SC("ready\n"));
- _ready=true;
- break;
- default:
- scprintf(_SC("unknown packet"));
-
- }
-}
-
-/*
- see copyright notice in sqrdbg.h
-*/
-bool SQDbgServer::ParseBreakpoint(const char *msg,BreakPoint &out)
-{
- static char stemp[MAX_BP_PATH];
- char *ep=NULL;
- out._line=strtoul(msg,&ep,16);
- if(ep==msg || (*ep)!=':')return false;
-
- char *dest=stemp;
- ep++;
- while((*ep)!='\n' && (*ep)!='\0')
- {
- *dest=*ep;
- *dest++;*ep++;
- }
- *dest='\0';
- *dest++;
- *dest='\0';
-#ifdef _UNICODE
- int len=(int)strlen(stemp);
- SQChar *p=sq_getscratchpad(_v,(SQInteger)(mbstowcs(NULL,stemp,len)+2)*sizeof(SQChar));
- size_t destlen=mbstowcs(p,stemp,len);
- p[destlen]=_SC('\0');
- out._src=p;
-#else
- out._src=stemp;
-#endif
- return true;
-}
-
-bool SQDbgServer::ParseWatch(const char *msg,Watch &out)
-{
- char *ep=NULL;
- out._id=strtoul(msg,&ep,16);
- if(ep==msg || (*ep)!=':')return false;
-
- //char *dest=out._src;
- ep++;
- while((*ep)!='\n' && (*ep)!='\0')
- {
- out._exp.append(1,*ep);
- *ep++;
- }
- return true;
-}
-
-bool SQDbgServer::ParseRemoveWatch(const char *msg,int &id)
-{
- char *ep=NULL;
- id=strtoul(msg,&ep,16);
- if(ep==msg)return false;
- return true;
-}
-
-
-void SQDbgServer::BreakExecution()
-{
- _state=eDBG_Suspended;
- while(_state==eDBG_Suspended){
- if(SQ_FAILED(sq_rdbg_update(this)))
- exit(0);
- usleep(10);
- }
-}
-
-//COMMANDS
-void SQDbgServer::AddBreakpoint(BreakPoint &bp)
-{
- _breakpoints.insert(bp);
- BeginDocument();
- BeginElement(_SC("addbreakpoint"));
- Attribute(_SC("line"),IntToString(bp._line));
- Attribute(_SC("src"),bp._src.c_str());
- EndElement(_SC("addbreakpoint"));
- EndDocument();
-}
-
-void SQDbgServer::AddWatch(Watch &w)
-{
- _watches.insert(w);
-}
-
-void SQDbgServer::RemoveWatch(int id)
-{
- WatchSetItor itor=_watches.find(Watch(id,_SC("")));
- if(itor==_watches.end()){
- BeginDocument();
- BeginElement(_SC("error"));
- Attribute(_SC("desc"),_SC("the watch does not exists"));
- EndElement(_SC("error"));
- EndDocument();
- }
- else{
- _watches.erase(itor);
- scprintf(_SC("removed watch %d\n"),id);
- }
-}
-
-void SQDbgServer::RemoveBreakpoint(BreakPoint &bp)
-{
- BreakPointSetItor itor=_breakpoints.find(bp);
- if(itor==_breakpoints.end()){
- BeginDocument();
- BeginElement(_SC("break"));
- Attribute(_SC("desc"),_SC("the breakpoint doesn't exists"));
- EndElement(_SC("break"));
- EndDocument();
- }
- else{
- BeginDocument();
- BeginElement(_SC("removebreakpoint"));
- Attribute(_SC("line"),IntToString(bp._line));
- Attribute(_SC("src"),bp._src.c_str());
- EndElement(_SC("removebreakpoint"));
- EndDocument();
- _breakpoints.erase(itor);
- }
-}
-
-void SQDbgServer::Break(int line,const SQChar *src,const SQChar *type,const SQChar *error)
-{
- if(!error){
- BeginDocument();
- BeginElement(_SC("break"));
- Attribute(_SC("line"),IntToString(line));
- Attribute(_SC("src"),src);
- Attribute(_SC("type"),type);
- SerializeState();
- EndElement(_SC("break"));
- EndDocument();
- }else{
- BeginDocument();
- BeginElement(_SC("break"));
- Attribute(_SC("line"),IntToString(line));
- Attribute(_SC("src"),src);
- Attribute(_SC("type"),type);
- Attribute(_SC("error"),error);
- SerializeState();
- EndElement(_SC("break"));
- EndDocument();
- }
-}
-
-void SQDbgServer::SerializeState()
-{
- sq_pushnull(_v);
- sq_setdebughook(_v);
- sq_pushnull(_v);
- sq_seterrorhandler(_v);
- const SQChar *sz;
- sq_pushobject(_v,_serializefunc);
- sq_pushobject(_v,_debugroot);
- sq_pushstring(_v,_SC("watches"),-1);
- sq_newtable(_v);
- for(WatchSetItor i=_watches.begin(); i!=_watches.end(); ++i)
- {
- sq_pushinteger(_v,i->_id);
- sq_pushstring(_v,i->_exp.c_str(),(int)i->_exp.length());
- sq_createslot(_v,-3);
- }
- sq_rawset(_v,-3);
- if(SQ_SUCCEEDED(sq_call(_v,1,SQTrue,SQTrue))){
- if(SQ_SUCCEEDED(sqstd_getblob(_v,-1,(SQUserPointer*)&sz)))
- SendChunk(sz);
- }
- sq_pop(_v,2);
-
- SetErrorHandlers();
-}
-
-
-void SQDbgServer::SetErrorHandlers()
-{
- sq_pushregistrytable(_v);
- sq_pushstring(_v,SQDBG_DEBUG_HOOK,-1);
- sq_rawget(_v,-2);
- sq_setdebughook(_v);
- sq_pushstring(_v,SQDBG_ERROR_HANDLER,-1);
- sq_rawget(_v,-2);
- sq_seterrorhandler(_v);
- sq_pop(_v,1);
-}
-
-void SQDbgServer::BeginElement(const SQChar *name)
-{
- _xmlcurrentement++;
- XMLElementState *self = &xmlstate[_xmlcurrentement];
- scstrcpy(self->name,name);
- self->haschildren = false;
- if(_xmlcurrentement > 0) {
- XMLElementState *parent = &xmlstate[_xmlcurrentement-1];
- if(!parent->haschildren) {
- SendChunk(_SC(">")); // closes the parent tag
- parent->haschildren = true;
- }
- }
- _scratchstring.resize(2+scstrlen(name));
- scsprintf(&_scratchstring[0],_SC("<%s"),name);
- SendChunk(&_scratchstring[0]);
-}
-
-void SQDbgServer::Attribute(const SQChar *name,const SQChar *value)
-{
- XMLElementState *self = &xmlstate[_xmlcurrentement];
- assert(!self->haschildren); //cannot have attributes if already has children
- const SQChar *escval = escape_xml(value);
- _scratchstring.resize(5+scstrlen(name)+scstrlen(escval));
- scsprintf(&_scratchstring[0],_SC(" %s=\"%s\""),name,escval);
- SendChunk(&_scratchstring[0]);
-}
-
-void SQDbgServer::EndElement(const SQChar *name)
-{
- XMLElementState *self = &xmlstate[_xmlcurrentement];
- assert(scstrcmp(self->name,name) == 0);
- if(self->haschildren) {
- _scratchstring.resize(4+scstrlen(name));
- scsprintf(&_scratchstring[0],_SC("</%s>"),name);
- SendChunk(&_scratchstring[0]);
-
- }
- else {
- SendChunk(_SC("/>"));
- }
- _xmlcurrentement--;
-}
-
-void SQDbgServer::EndDocument()
-{
- SendChunk(_SC("\r\n"));
-}
-
-//this can be done much better/faster(do we need that?)
-const SQChar *SQDbgServer::escape_xml(const SQChar *s)
-{
- SQChar *temp=sq_getscratchpad(_v,((int)scstrlen(s)*6) + sizeof(SQChar));
- SQChar *dest=temp;
- while(*s!=_SC('\0')){
- int i=0;
- bool escaped=false;
- while(g_escapes[i].esc!=NULL){
- if(*s==g_escapes[i].c){
- scstrcpy(dest,g_escapes[i].esc);
- dest+=scstrlen(g_escapes[i].esc);
- escaped=true;
- break;
- }
- i++;
- }
- if(!escaped){*dest=*s;*dest++;}
- *s++;
- }
- *dest=_SC('\0');
- return temp;
-
-}
+++ /dev/null
-#ifndef _SQ_DBGSERVER_H_
-#define _SQ_DBGSERVER_H_
-
-#define MAX_BP_PATH 512
-#define MAX_MSG_LEN 2049
-
-#include <set>
-#include <string>
-#include <vector>
-
-#ifdef _WIN32
-#include <winsock.h>
-#define sqdbg_closesocket(x) closesocket((x))
-typedef socklen_t int;
-#else
-#include <unistd.h>
-#include <errno.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <fcntl.h>
-
-#define sqdbg_closesocket(x) close((x))
-typedef int SOCKET;
-typedef struct timeval TIMEVAL;
-#define SOCKET_ERROR -1
-#define INVALID_SOCKET -1
-#endif
-
-typedef std::basic_string<SQChar> SQDBGString;
-
-inline bool dbg_less(const SQChar *x,const SQChar *y)
-{
- // [SuperTux] commented out to avoid compiler warning
- //int n = 0;
- do {
- int xl = *x == '\\' ? '/' : tolower(*x);
- int yl = *y == '\\' ? '/' : tolower(*y);
- int diff = xl - yl;
- if(diff != 0)
- return diff > 0?true:false;
- x++; y++;
- }while(*x != 0 && *y != 0);
- return false;
-}
-
-struct BreakPoint{
- BreakPoint(){_line=0;}
- BreakPoint(int line, const SQChar *src){ _line = line; _src = src; }
- BreakPoint(const BreakPoint& bp){ _line = bp._line; _src=bp._src; }
- inline bool operator<(const BreakPoint& bp) const
- {
- if(_line<bp._line)
- return true;
- if(_line==bp._line){
- return dbg_less(_src.c_str(),bp._src.c_str());
- }
- return false;
- }
-
- int _line;
- SQDBGString _src;
-};
-
-struct Watch{
- Watch() { _id = 0; }
- Watch(int id,const SQChar *exp) { _id = id; _exp = exp; }
- Watch(const Watch &w) { _id = w._id; _exp = w._exp; }
- bool operator<(const Watch& w) const { return _id<w._id; }
- bool operator==(const Watch& w) const { return _id == w._id; }
- int _id;
- SQDBGString _exp;
-};
-
-typedef std::set<BreakPoint> BreakPointSet;
-typedef BreakPointSet::iterator BreakPointSetItor;
-
-typedef std::set<Watch> WatchSet;
-typedef WatchSet::iterator WatchSetItor;
-
-typedef std::vector<SQChar> SQCharVec;
-struct SQDbgServer{
-public:
- enum eDbgState{
- eDBG_Running,
- eDBG_StepOver,
- eDBG_StepInto,
- eDBG_StepReturn,
- eDBG_Suspended,
- eDBG_Disabled,
- };
-
- SQDbgServer(HSQUIRRELVM v);
- ~SQDbgServer();
- bool Init();
- //returns true if a message has been received
- bool WaitForClient();
- bool ReadMsg();
- void BusyWait();
- void Hook(int type,int line,const SQChar *src,const SQChar *func);
- void ParseMsg(const char *msg);
- bool ParseBreakpoint(const char *msg,BreakPoint &out);
- bool ParseWatch(const char *msg,Watch &out);
- bool ParseRemoveWatch(const char *msg,int &id);
- void Terminated();
- //
- void BreakExecution();
- void Send(const SQChar *s,...);
- void SendChunk(const SQChar *chunk);
- void Break(int line,const SQChar *src,const SQChar *type,const SQChar *error=NULL);
-
-
- void SerializeState();
- //COMMANDS
- void AddBreakpoint(BreakPoint &bp);
- void AddWatch(Watch &w);
- void RemoveWatch(int id);
- void RemoveBreakpoint(BreakPoint &bp);
-
- //
- void SetErrorHandlers();
-
- //XML RELATED STUFF///////////////////////
- #define MAX_NESTING 10
- struct XMLElementState {
- SQChar name[256];
- bool haschildren;
- };
-
- XMLElementState xmlstate[MAX_NESTING];
- int _xmlcurrentement;
-
- void BeginDocument() { _xmlcurrentement = -1; }
- void BeginElement(const SQChar *name);
- void Attribute(const SQChar *name, const SQChar *value);
- void EndElement(const SQChar *name);
- void EndDocument();
-
- const SQChar *escape_xml(const SQChar *x);
- //////////////////////////////////////////////
- HSQUIRRELVM _v;
- HSQOBJECT _debugroot;
- eDbgState _state;
- SOCKET _accept;
- SOCKET _endpoint;
- BreakPointSet _breakpoints;
- WatchSet _watches;
- int _recursionlevel;
- int _maxrecursion;
- int _nestedcalls;
- bool _ready;
- bool _autoupdate;
- HSQOBJECT _serializefunc;
- SQCharVec _scratchstring;
-
-};
-
-#endif //_SQ_DBGSERVER_H_
+++ /dev/null
-/*
- see copyright notice in sqrdbg.h
-*/
-#include <squirrel.h>
-#include "sqrdbg.h"
-#include "sqdbgserver.h"
-SQInteger debug_hook(HSQUIRRELVM v);
-SQInteger error_handler(HSQUIRRELVM v);
-
-#include "serialize_state.inl"
-
-HSQREMOTEDBG sq_rdbg_init(HSQUIRRELVM v,unsigned short port,SQBool autoupdate)
-{
- sockaddr_in bindaddr;
-#ifdef _WIN32
- WSADATA wsadata;
- if (WSAStartup (MAKEWORD(1,1), &wsadata) != 0){
- return NULL;
- }
-#endif
-
- SQDbgServer *rdbg = new SQDbgServer(v);
- rdbg->_autoupdate = autoupdate?true:false;
- rdbg->_accept = socket(AF_INET,SOCK_STREAM,0);
- bindaddr.sin_family = AF_INET;
- bindaddr.sin_port = htons(port);
- bindaddr.sin_addr.s_addr = htonl (INADDR_ANY);
- if(bind(rdbg->_accept,(sockaddr*)&bindaddr,sizeof(bindaddr))==SOCKET_ERROR){
- delete rdbg;
- sq_throwerror(v,_SC("failed to bind the socket"));
- return NULL;
- }
- if(!rdbg->Init()) {
- delete rdbg;
- sq_throwerror(v,_SC("failed to initialize the debugger"));
- return NULL;
- }
-
- return rdbg;
-}
-
-SQRESULT sq_rdbg_waitforconnections(HSQREMOTEDBG rdbg)
-{
- if(SQ_FAILED(sq_compilebuffer(rdbg->_v,serialize_state_nut,(SQInteger)scstrlen(serialize_state_nut),_SC("SERIALIZE_STATE"),SQFalse))) {
- sq_throwerror(rdbg->_v,_SC("error compiling the serialization function"));
- }
- sq_getstackobj(rdbg->_v,-1,&rdbg->_serializefunc);
- sq_addref(rdbg->_v,&rdbg->_serializefunc);
- sq_pop(rdbg->_v,1);
-
- sockaddr_in cliaddr;
- socklen_t addrlen=sizeof(cliaddr);
- if(listen(rdbg->_accept,0)==SOCKET_ERROR)
- return sq_throwerror(rdbg->_v,_SC("error on listen(socket)"));
- rdbg->_endpoint = accept(rdbg->_accept,(sockaddr*)&cliaddr,&addrlen);
- //do not accept any other connection
- sqdbg_closesocket(rdbg->_accept);
- rdbg->_accept = INVALID_SOCKET;
- if(rdbg->_endpoint==INVALID_SOCKET){
- return sq_throwerror(rdbg->_v,_SC("error accept(socket)"));
- }
- while(!rdbg->_ready){
- sq_rdbg_update(rdbg);
- }
- return SQ_OK;
-}
-
-SQRESULT sq_rdbg_update(HSQREMOTEDBG rdbg)
-{
- TIMEVAL time;
- time.tv_sec=0;
- time.tv_usec=0;
- fd_set read_flags;
- FD_ZERO(&read_flags);
- FD_SET(rdbg->_endpoint, &read_flags);
- select(FD_SETSIZE, &read_flags, NULL, NULL, &time);
-
- if(FD_ISSET(rdbg->_endpoint,&read_flags)){
- char temp[1024];
- int size=0;
- char c,prev=0;
- memset(&temp,0,sizeof(temp));
- int res;
- FD_CLR(rdbg->_endpoint, &read_flags);
- while((res = recv(rdbg->_endpoint,&c,1,0))>0){
-
- if(c=='\n')break;
- if(c!='\r'){
- temp[size]=c;
- prev=c;
- size++;
- }
- }
- switch(res){
- case 0:
- return sq_throwerror(rdbg->_v,_SC("disconnected"));
- case SOCKET_ERROR:
- return sq_throwerror(rdbg->_v,_SC("socket error"));
- }
-
- temp[size]=0;
- temp[size+1]=0;
- rdbg->ParseMsg(temp);
- }
- return SQ_OK;
-}
-
-SQInteger debug_hook(HSQUIRRELVM v)
-{
- SQUserPointer up;
- SQInteger event_type,line;
- const SQChar *src,*func;
- sq_getinteger(v,2,&event_type);
- sq_getstring(v,3,&src);
- sq_getinteger(v,4,&line);
- sq_getstring(v,5,&func);
- sq_getuserpointer(v,-1,&up);
- HSQREMOTEDBG rdbg = (HSQREMOTEDBG)up;
- rdbg->Hook(event_type,line,src,func);
- if(rdbg->_autoupdate) {
- if(SQ_FAILED(sq_rdbg_update(rdbg)))
- return sq_throwerror(v,_SC("socket failed"));
- }
- return 0;
-}
-
-SQInteger error_handler(HSQUIRRELVM v)
-{
- SQUserPointer up;
- const SQChar *sErr=NULL;
- const SQChar *fn=_SC("unknown");
- const SQChar *src=_SC("unknown");
- int line=-1;
- SQStackInfos si;
- sq_getuserpointer(v,-1,&up);
- HSQREMOTEDBG rdbg=(HSQREMOTEDBG)up;
- if(SQ_SUCCEEDED(sq_stackinfos(v,1,&si)))
- {
- if(si.funcname)fn=si.funcname;
- if(si.source)src=si.source;
- line=si.line;
- scprintf(_SC("*FUNCTION [%s] %s line [%d]\n"),fn,src,si.line);
- }
- if(sq_gettop(v)>=1){
- if(SQ_SUCCEEDED(sq_getstring(v,2,&sErr))) {
- scprintf(_SC("\nAN ERROR HAS OCCURED [%s]\n"),sErr);
- rdbg->Break(si.line,src,_SC("error"),sErr);
- }
- else{
- scprintf(_SC("\nAN ERROR HAS OCCURED [unknown]\n"));
- rdbg->Break(si.line,src,_SC("error"),_SC("unknown"));
- }
- }
- rdbg->BreakExecution();
- return 0;
-}
-
-
-SQRESULT sq_rdbg_shutdown(HSQREMOTEDBG rdbg)
-{
- delete rdbg;
-#ifdef _WIN32
- WSACleanup();
-#endif
- return SQ_OK;
-}
+++ /dev/null
-/*
-Copyright (c) 2003-2005 Alberto Demichelis
-
-This software is provided 'as-is', without any
-express or implied warranty. In no event will the
-authors be held liable for any damages arising from
-the use of this software.
-
-Permission is granted to anyone to use this software
-for any purpose, including commercial applications,
-and to alter it and redistribute it freely, subject
-to the following restrictions:
-
- 1. The origin of this software must not be
- misrepresented; you must not claim that
- you wrote the original software. If you
- use this software in a product, an
- acknowledgment in the product
- documentation would be appreciated but is
- not required.
-
- 2. Altered source versions must be plainly
- marked as such, and must not be
- misrepresented as being the original
- software.
-
- 3. This notice may not be removed or
- altered from any source distribution.
-
-*/
-#ifndef _SQ_RDBG_H_
-#define _SQ_RDBG_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct SQDbgServer;
-typedef SQDbgServer* HSQREMOTEDBG;
-
-HSQREMOTEDBG sq_rdbg_init(HSQUIRRELVM v,unsigned short port,SQBool autoupdate);
-SQRESULT sq_rdbg_waitforconnections(HSQREMOTEDBG rdbg);
-SQRESULT sq_rdbg_shutdown(HSQREMOTEDBG rdbg);
-SQRESULT sq_rdbg_update(HSQREMOTEDBG rdbg);
-
-#ifdef __cplusplus
-} /*extern "C"*/
-#endif
-
-#endif //_SQ_RDBG_H_
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#include <squirrel.h>
-#include <sqstdaux.h>
-#include <assert.h>
-
-void sqstd_printcallstack(HSQUIRRELVM v)
-{
- SQPRINTFUNCTION pf = sq_getprintfunc(v);
- if(pf) {
- SQStackInfos si;
- SQInteger i;
- SQBool b;
- SQFloat f;
- const SQChar *s;
- SQInteger level=1; //1 is to skip this function that is level 0
- const SQChar *name=0;
- SQInteger seq=0;
- pf(v,_SC("\nCALLSTACK\n"));
- while(SQ_SUCCEEDED(sq_stackinfos(v,level,&si)))
- {
- const SQChar *fn=_SC("unknown");
- const SQChar *src=_SC("unknown");
- if(si.funcname)fn=si.funcname;
- if(si.source)src=si.source;
- pf(v,_SC("*FUNCTION [%s()] %s line [%d]\n"),fn,src,si.line);
- level++;
- }
- level=0;
- pf(v,_SC("\nLOCALS\n"));
-
- for(level=0;level<10;level++){
- seq=0;
- while((name = sq_getlocal(v,level,seq)))
- {
- seq++;
- switch(sq_gettype(v,-1))
- {
- case OT_NULL:
- pf(v,_SC("[%s] NULL\n"),name);
- break;
- case OT_INTEGER:
- sq_getinteger(v,-1,&i);
- pf(v,_SC("[%s] %d\n"),name,i);
- break;
- case OT_FLOAT:
- sq_getfloat(v,-1,&f);
- pf(v,_SC("[%s] %.14g\n"),name,f);
- break;
- case OT_USERPOINTER:
- pf(v,_SC("[%s] USERPOINTER\n"),name);
- break;
- case OT_STRING:
- sq_getstring(v,-1,&s);
- pf(v,_SC("[%s] \"%s\"\n"),name,s);
- break;
- case OT_TABLE:
- pf(v,_SC("[%s] TABLE\n"),name);
- break;
- case OT_ARRAY:
- pf(v,_SC("[%s] ARRAY\n"),name);
- break;
- case OT_CLOSURE:
- pf(v,_SC("[%s] CLOSURE\n"),name);
- break;
- case OT_NATIVECLOSURE:
- pf(v,_SC("[%s] NATIVECLOSURE\n"),name);
- break;
- case OT_GENERATOR:
- pf(v,_SC("[%s] GENERATOR\n"),name);
- break;
- case OT_USERDATA:
- pf(v,_SC("[%s] USERDATA\n"),name);
- break;
- case OT_THREAD:
- pf(v,_SC("[%s] THREAD\n"),name);
- break;
- case OT_CLASS:
- pf(v,_SC("[%s] CLASS\n"),name);
- break;
- case OT_INSTANCE:
- pf(v,_SC("[%s] INSTANCE\n"),name);
- break;
- case OT_WEAKREF:
- pf(v,_SC("[%s] WEAKREF\n"),name);
- break;
- case OT_BOOL:{
- sq_getbool(v,-1,&b);
- pf(v,_SC("[%s] %s\n"),name,b?_SC("true"):_SC("false"));
- }
- break;
- default: assert(0); break;
- }
- sq_pop(v,1);
- }
- }
- }
-}
-
-static SQInteger _sqstd_aux_printerror(HSQUIRRELVM v)
-{
- SQPRINTFUNCTION pf = sq_getprintfunc(v);
- if(pf) {
- const SQChar *sErr = 0;
- if(sq_gettop(v)>=1) {
- if(SQ_SUCCEEDED(sq_getstring(v,2,&sErr))) {
- pf(v,_SC("\nAN ERROR HAS OCCURED [%s]\n"),sErr);
- }
- else{
- pf(v,_SC("\nAN ERROR HAS OCCURED [unknown]\n"));
- }
- sqstd_printcallstack(v);
- }
- }
- return 0;
-}
-
-void _sqstd_compiler_error(HSQUIRRELVM v,const SQChar *sErr,const SQChar *sSource,SQInteger line,SQInteger column)
-{
- SQPRINTFUNCTION pf = sq_getprintfunc(v);
- if(pf) {
- pf(v,_SC("%s line = (%d) column = (%d) : error %s\n"),sSource,line,column,sErr);
- }
-}
-
-void sqstd_seterrorhandlers(HSQUIRRELVM v)
-{
- sq_setcompilererrorhandler(v,_sqstd_compiler_error);
- sq_newclosure(v,_sqstd_aux_printerror,0);
- sq_seterrorhandler(v);
-}
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#include <new>
-#include <squirrel.h>
-#include <sqstdio.h>
-#include <string.h>
-#include <sqstdblob.h>
-#include "sqstdstream.h"
-#include "sqstdblobimpl.h"
-
-#define SQSTD_BLOB_TYPE_TAG (SQSTD_STREAM_TYPE_TAG | 0x00000002)
-
-//Blob
-
-
-#define SETUP_BLOB(v) \
- SQBlob *self = NULL; \
- { if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) \
- return SQ_ERROR; }
-
-
-static SQInteger _blob_resize(HSQUIRRELVM v)
-{
- SETUP_BLOB(v);
- SQInteger size;
- sq_getinteger(v,2,&size);
- if(!self->Resize(size))
- return sq_throwerror(v,_SC("resize failed"));
- return 0;
-}
-
-static void __swap_dword(unsigned int *n)
-{
- *n=(unsigned int)(((*n&0xFF000000)>>24) |
- ((*n&0x00FF0000)>>8) |
- ((*n&0x0000FF00)<<8) |
- ((*n&0x000000FF)<<24));
-}
-
-static void __swap_word(unsigned short *n)
-{
- *n=(unsigned short)((*n>>8)&0x00FF)| ((*n<<8)&0xFF00);
-}
-
-static SQInteger _blob_swap4(HSQUIRRELVM v)
-{
- SETUP_BLOB(v);
- SQInteger num=(self->Len()-(self->Len()%4))>>2;
- unsigned int *t=(unsigned int *)self->GetBuf();
- for(SQInteger i = 0; i < num; i++) {
- __swap_dword(&t[i]);
- }
- return 0;
-}
-
-static SQInteger _blob_swap2(HSQUIRRELVM v)
-{
- SETUP_BLOB(v);
- SQInteger num=(self->Len()-(self->Len()%2))>>1;
- unsigned short *t = (unsigned short *)self->GetBuf();
- for(SQInteger i = 0; i < num; i++) {
- __swap_word(&t[i]);
- }
- return 0;
-}
-
-static SQInteger _blob__set(HSQUIRRELVM v)
-{
- SETUP_BLOB(v);
- SQInteger idx,val;
- sq_getinteger(v,2,&idx);
- sq_getinteger(v,3,&val);
- if(idx < 0 || idx >= self->Len())
- return sq_throwerror(v,_SC("index out of range"));
- ((unsigned char *)self->GetBuf())[idx] = (unsigned char) val;
- sq_push(v,3);
- return 1;
-}
-
-static SQInteger _blob__get(HSQUIRRELVM v)
-{
- SETUP_BLOB(v);
- SQInteger idx;
- sq_getinteger(v,2,&idx);
- if(idx < 0 || idx >= self->Len())
- return sq_throwerror(v,_SC("index out of range"));
- sq_pushinteger(v,((unsigned char *)self->GetBuf())[idx]);
- return 1;
-}
-
-static SQInteger _blob__nexti(HSQUIRRELVM v)
-{
- SETUP_BLOB(v);
- if(sq_gettype(v,2) == OT_NULL) {
- sq_pushinteger(v, 0);
- return 1;
- }
- SQInteger idx;
- if(SQ_SUCCEEDED(sq_getinteger(v, 2, &idx))) {
- if(idx+1 < self->Len()) {
- sq_pushinteger(v, idx+1);
- return 1;
- }
- sq_pushnull(v);
- return 1;
- }
- return sq_throwerror(v,_SC("internal error (_nexti) wrong argument type"));
-}
-
-static SQInteger _blob__typeof(HSQUIRRELVM v)
-{
- sq_pushstring(v,_SC("blob"),-1);
- return 1;
-}
-
-static SQInteger _blob_releasehook(SQUserPointer p, SQInteger size)
-{
- SQBlob *self = (SQBlob*)p;
- delete self;
- return 1;
-}
-
-static SQInteger _blob_constructor(HSQUIRRELVM v)
-{
- SQInteger nparam = sq_gettop(v);
- SQInteger size = 0;
- if(nparam == 2) {
- sq_getinteger(v, 2, &size);
- }
- if(size < 0) return sq_throwerror(v, _SC("cannot create blob with negative size"));
- SQBlob *b = new SQBlob(size);
- if(SQ_FAILED(sq_setinstanceup(v,1,b))) {
- delete b;
- return sq_throwerror(v, _SC("cannot create blob with negative size"));
- }
- sq_setreleasehook(v,1,_blob_releasehook);
- return 0;
-}
-
-#define _DECL_BLOB_FUNC(name,nparams,typecheck) {_SC(#name),_blob_##name,nparams,typecheck}
-static SQRegFunction _blob_methods[] = {
- _DECL_BLOB_FUNC(constructor,-1,_SC("xn")),
- _DECL_BLOB_FUNC(resize,2,_SC("xn")),
- _DECL_BLOB_FUNC(swap2,1,_SC("x")),
- _DECL_BLOB_FUNC(swap4,1,_SC("x")),
- _DECL_BLOB_FUNC(_set,3,_SC("xnn")),
- _DECL_BLOB_FUNC(_get,2,_SC("xn")),
- _DECL_BLOB_FUNC(_typeof,1,_SC("x")),
- _DECL_BLOB_FUNC(_nexti,2,_SC("x")),
- {0,0,0,0}
-};
-
-
-
-//GLOBAL FUNCTIONS
-
-static SQInteger _g_blob_casti2f(HSQUIRRELVM v)
-{
- SQInteger i;
- sq_getinteger(v,2,&i);
- sq_pushfloat(v,*((SQFloat *)&i));
- return 1;
-}
-
-static SQInteger _g_blob_castf2i(HSQUIRRELVM v)
-{
- SQFloat f;
- sq_getfloat(v,2,&f);
- sq_pushinteger(v,*((SQInteger *)&f));
- return 1;
-}
-
-static SQInteger _g_blob_swap2(HSQUIRRELVM v)
-{
- SQInteger i;
- sq_getinteger(v,2,&i);
- short s=(short)i;
- sq_pushinteger(v,(s<<8)|((s>>8)&0x00FF));
- return 1;
-}
-
-static SQInteger _g_blob_swap4(HSQUIRRELVM v)
-{
- SQInteger i;
- sq_getinteger(v,2,&i);
- unsigned int t4 = (unsigned int)i;
- __swap_dword(&t4);
- sq_pushinteger(v,(SQInteger)t4);
- return 1;
-}
-
-static SQInteger _g_blob_swapfloat(HSQUIRRELVM v)
-{
- SQFloat f;
- sq_getfloat(v,2,&f);
- __swap_dword((unsigned int *)&f);
- sq_pushfloat(v,f);
- return 1;
-}
-
-#define _DECL_GLOBALBLOB_FUNC(name,nparams,typecheck) {_SC(#name),_g_blob_##name,nparams,typecheck}
-static SQRegFunction bloblib_funcs[]={
- _DECL_GLOBALBLOB_FUNC(casti2f,2,_SC(".n")),
- _DECL_GLOBALBLOB_FUNC(castf2i,2,_SC(".n")),
- _DECL_GLOBALBLOB_FUNC(swap2,2,_SC(".n")),
- _DECL_GLOBALBLOB_FUNC(swap4,2,_SC(".n")),
- _DECL_GLOBALBLOB_FUNC(swapfloat,2,_SC(".n")),
- {0,0}
-};
-
-SQRESULT sqstd_getblob(HSQUIRRELVM v,SQInteger idx,SQUserPointer *ptr)
-{
- SQBlob *blob;
- if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG)))
- return -1;
- *ptr = blob->GetBuf();
- return SQ_OK;
-}
-
-SQInteger sqstd_getblobsize(HSQUIRRELVM v,SQInteger idx)
-{
- SQBlob *blob;
- if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG)))
- return -1;
- return blob->Len();
-}
-
-SQUserPointer sqstd_createblob(HSQUIRRELVM v, SQInteger size)
-{
- SQInteger top = sq_gettop(v);
- sq_pushregistrytable(v);
- sq_pushstring(v,_SC("std_blob"),-1);
- if(SQ_SUCCEEDED(sq_get(v,-2))) {
- sq_remove(v,-2); //removes the registry
- sq_push(v,1); // push the this
- sq_pushinteger(v,size); //size
- SQBlob *blob = NULL;
- if(SQ_SUCCEEDED(sq_call(v,2,SQTrue,SQFalse))
- && SQ_SUCCEEDED(sq_getinstanceup(v,-1,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) {
- sq_remove(v,-2);
- return blob->GetBuf();
- }
- }
- sq_settop(v,top);
- return NULL;
-}
-
-SQRESULT sqstd_register_bloblib(HSQUIRRELVM v)
-{
- return declare_stream(v,_SC("blob"),(SQUserPointer)SQSTD_BLOB_TYPE_TAG,_SC("std_blob"),_blob_methods,bloblib_funcs);
-}
-
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQSTD_BLOBIMPL_H_
-#define _SQSTD_BLOBIMPL_H_
-
-struct SQBlob : public SQStream
-{
- SQBlob(SQInteger size) {
- _size = size;
- _allocated = size;
- _buf = (unsigned char *)sq_malloc(size);
- memset(_buf, 0, _size);
- _ptr = 0;
- _owns = true;
- }
- virtual ~SQBlob() {
- sq_free(_buf, _allocated);
- }
- SQInteger Write(void *buffer, SQInteger size) {
- if(!CanAdvance(size)) {
- GrowBufOf(_ptr + size - _size);
- }
- memcpy(&_buf[_ptr], buffer, size);
- _ptr += size;
- return size;
- }
- SQInteger Read(void *buffer,SQInteger size) {
- SQInteger n = size;
- if(!CanAdvance(size)) {
- if((_size - _ptr) > 0)
- n = _size - _ptr;
- else return 0;
- }
- memcpy(buffer, &_buf[_ptr], n);
- _ptr += n;
- return n;
- }
- bool Resize(SQInteger n) {
- if(!_owns) return false;
- if(n != _allocated) {
- unsigned char *newbuf = (unsigned char *)sq_malloc(n);
- memset(newbuf,0,n);
- if(_size > n)
- memcpy(newbuf,_buf,n);
- else
- memcpy(newbuf,_buf,_size);
- sq_free(_buf,_allocated);
- _buf=newbuf;
- _allocated = n;
- if(_size > _allocated)
- _size = _allocated;
- if(_ptr > _allocated)
- _ptr = _allocated;
- }
- return true;
- }
- bool GrowBufOf(SQInteger n)
- {
- bool ret = true;
- if(_size + n > _allocated) {
- if(_size + n > _size * 2)
- ret = Resize(_size + n);
- else
- ret = Resize(_size * 2);
- }
- _size = _size + n;
- return ret;
- }
- bool CanAdvance(SQInteger n) {
- if(_ptr+n>_size)return false;
- return true;
- }
- SQInteger Seek(SQInteger offset, SQInteger origin) {
- switch(origin) {
- case SQ_SEEK_SET:
- if(offset > _size || offset < 0) return -1;
- _ptr = offset;
- break;
- case SQ_SEEK_CUR:
- if(_ptr + offset > _size || _ptr + offset < 0) return -1;
- _ptr += offset;
- break;
- case SQ_SEEK_END:
- if(_size + offset > _size || _size + offset < 0) return -1;
- _ptr = _size + offset;
- break;
- default: return -1;
- }
- return 0;
- }
- bool IsValid() {
- return _buf?true:false;
- }
- bool EOS() {
- return _ptr == _size;
- }
- SQInteger Flush() { return 0; }
- SQInteger Tell() { return _ptr; }
- SQInteger Len() { return _size; }
- SQUserPointer GetBuf(){ return _buf; }
-private:
- SQInteger _size;
- SQInteger _allocated;
- SQInteger _ptr;
- unsigned char *_buf;
- bool _owns;
-};
-
-#endif //_SQSTD_BLOBIMPL_H_
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#include <new>
-#include <stdio.h>
-#include <squirrel.h>
-#include <sqstdio.h>
-#include "sqstdstream.h"
-
-#define SQSTD_FILE_TYPE_TAG (SQSTD_STREAM_TYPE_TAG | 0x00000001)
-//basic API
-SQFILE sqstd_fopen(const SQChar *filename ,const SQChar *mode)
-{
-#ifndef SQUNICODE
- return (SQFILE)fopen(filename,mode);
-#else
- return (SQFILE)_wfopen(filename,mode);
-#endif
-}
-
-SQInteger sqstd_fread(void* buffer, SQInteger size, SQInteger count, SQFILE file)
-{
- return (SQInteger)fread(buffer,size,count,(FILE *)file);
-}
-
-SQInteger sqstd_fwrite(const SQUserPointer buffer, SQInteger size, SQInteger count, SQFILE file)
-{
- return (SQInteger)fwrite(buffer,size,count,(FILE *)file);
-}
-
-SQInteger sqstd_fseek(SQFILE file, SQInteger offset, SQInteger origin)
-{
- SQInteger realorigin;
- switch(origin) {
- case SQ_SEEK_CUR: realorigin = SEEK_CUR; break;
- case SQ_SEEK_END: realorigin = SEEK_END; break;
- case SQ_SEEK_SET: realorigin = SEEK_SET; break;
- default: return -1; //failed
- }
- return fseek((FILE *)file,(long)offset,(int)realorigin);
-}
-
-SQInteger sqstd_ftell(SQFILE file)
-{
- return ftell((FILE *)file);
-}
-
-SQInteger sqstd_fflush(SQFILE file)
-{
- return fflush((FILE *)file);
-}
-
-SQInteger sqstd_fclose(SQFILE file)
-{
- return fclose((FILE *)file);
-}
-
-SQInteger sqstd_feof(SQFILE file)
-{
- return feof((FILE *)file);
-}
-
-//File
-struct SQFile : public SQStream {
- SQFile() { _handle = NULL; _owns = false;}
- SQFile(SQFILE file, bool owns) { _handle = file; _owns = owns;}
- virtual ~SQFile() { Close(); }
- bool Open(const SQChar *filename ,const SQChar *mode) {
- Close();
- if( (_handle = sqstd_fopen(filename,mode)) ) {
- _owns = true;
- return true;
- }
- return false;
- }
- void Close() {
- if(_handle && _owns) {
- sqstd_fclose(_handle);
- _handle = NULL;
- _owns = false;
- }
- }
- SQInteger Read(void *buffer,SQInteger size) {
- return sqstd_fread(buffer,1,size,_handle);
- }
- SQInteger Write(void *buffer,SQInteger size) {
- return sqstd_fwrite(buffer,1,size,_handle);
- }
- SQInteger Flush() {
- return sqstd_fflush(_handle);
- }
- SQInteger Tell() {
- return sqstd_ftell(_handle);
- }
- SQInteger Len() {
- SQInteger prevpos=Tell();
- Seek(0,SQ_SEEK_END);
- SQInteger size=Tell();
- Seek(prevpos,SQ_SEEK_SET);
- return size;
- }
- SQInteger Seek(SQInteger offset, SQInteger origin) {
- return sqstd_fseek(_handle,offset,origin);
- }
- bool IsValid() { return _handle?true:false; }
- bool EOS() { return Tell()==Len()?true:false;}
- SQFILE GetHandle() {return _handle;}
-private:
- SQFILE _handle;
- bool _owns;
-};
-
-static SQInteger _file__typeof(HSQUIRRELVM v)
-{
- sq_pushstring(v,_SC("file"),-1);
- return 1;
-}
-
-static SQInteger _file_releasehook(SQUserPointer p, SQInteger size)
-{
- SQFile *self = (SQFile*)p;
- delete self;
- return 1;
-}
-
-static SQInteger _file_constructor(HSQUIRRELVM v)
-{
- const SQChar *filename,*mode;
- bool owns = true;
- SQFile *f;
- SQFILE newf;
- if(sq_gettype(v,2) == OT_STRING && sq_gettype(v,3) == OT_STRING) {
- sq_getstring(v, 2, &filename);
- sq_getstring(v, 3, &mode);
- newf = sqstd_fopen(filename, mode);
- if(!newf) return sq_throwerror(v, _SC("cannot open file"));
- } else if(sq_gettype(v,2) == OT_USERPOINTER) {
- owns = !(sq_gettype(v,3) == OT_NULL);
- sq_getuserpointer(v,2,&newf);
- } else {
- return sq_throwerror(v,_SC("wrong parameter"));
- }
- f = new SQFile(newf,owns);
- if(SQ_FAILED(sq_setinstanceup(v,1,f))) {
- delete f;
- return sq_throwerror(v, _SC("cannot create blob with negative size"));
- }
- sq_setreleasehook(v,1,_file_releasehook);
- return 0;
-}
-
-//bindings
-#define _DECL_FILE_FUNC(name,nparams,typecheck) {_SC(#name),_file_##name,nparams,typecheck}
-static SQRegFunction _file_methods[] = {
- _DECL_FILE_FUNC(constructor,3,_SC("x")),
- _DECL_FILE_FUNC(_typeof,1,_SC("x")),
- {0,0,0,0},
-};
-
-
-
-SQRESULT sqstd_createfile(HSQUIRRELVM v, SQFILE file,SQBool own)
-{
- SQInteger top = sq_gettop(v);
- sq_pushregistrytable(v);
- sq_pushstring(v,_SC("std_file"),-1);
- if(SQ_SUCCEEDED(sq_get(v,-2))) {
- sq_remove(v,-2); //removes the registry
- sq_pushroottable(v); // push the this
- sq_pushuserpointer(v,file); //file
- if(own){
- sq_pushinteger(v,1); //true
- }
- else{
- sq_pushnull(v); //false
- }
- if(SQ_SUCCEEDED( sq_call(v,3,SQTrue,SQFalse) )) {
- sq_remove(v,-2);
- return SQ_OK;
- }
- }
- sq_settop(v,top);
- return SQ_OK;
-}
-
-SQRESULT sqstd_getfile(HSQUIRRELVM v, SQInteger idx, SQFILE *file)
-{
- SQFile *fileobj = NULL;
- if(SQ_SUCCEEDED(sq_getinstanceup(v,idx,(SQUserPointer*)&fileobj,(SQUserPointer)SQSTD_FILE_TYPE_TAG))) {
- *file = fileobj->GetHandle();
- return SQ_OK;
- }
- return sq_throwerror(v,_SC("not a file"));
-}
-
-
-
-static SQInteger _io_file_lexfeed_ASCII(SQUserPointer file)
-{
- SQInteger ret;
- char c;
- if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) )
- return c;
- return 0;
-}
-
-static SQInteger _io_file_lexfeed_UTF8(SQUserPointer file)
-{
-#define READ() \
- if(sqstd_fread(&inchar,sizeof(inchar),1,(FILE *)file) != 1) \
- return 0;
-
- static const SQInteger utf8_lengths[16] =
- {
- 1,1,1,1,1,1,1,1, /* 0000 to 0111 : 1 byte (plain ASCII) */
- 0,0,0,0, /* 1000 to 1011 : not valid */
- 2,2, /* 1100, 1101 : 2 bytes */
- 3, /* 1110 : 3 bytes */
- 4 /* 1111 :4 bytes */
- };
- static unsigned char byte_masks[5] = {0,0,0x1f,0x0f,0x07};
- unsigned char inchar;
- SQInteger c = 0;
- READ();
- c = inchar;
- //
- if(c >= 0x80) {
- SQInteger tmp;
- SQInteger codelen = utf8_lengths[c>>4];
- if(codelen == 0)
- return 0;
- //"invalid UTF-8 stream";
- tmp = c&byte_masks[codelen];
- for(SQInteger n = 0; n < codelen-1; n++) {
- tmp<<=6;
- READ();
- tmp |= inchar & 0x3F;
- }
- c = tmp;
- }
- return c;
-}
-
-static SQInteger _io_file_lexfeed_UCS2_LE(SQUserPointer file)
-{
- SQInteger ret;
- wchar_t c;
- if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) )
- return (SQChar)c;
- return 0;
-}
-
-static SQInteger _io_file_lexfeed_UCS2_BE(SQUserPointer file)
-{
- SQInteger ret;
- unsigned short c;
- if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) ) {
- c = ((c>>8)&0x00FF)| ((c<<8)&0xFF00);
- return (SQChar)c;
- }
- return 0;
-}
-
-SQInteger file_read(SQUserPointer file,SQUserPointer buf,SQInteger size)
-{
- SQInteger ret;
- if( ( ret = sqstd_fread(buf,1,size,(SQFILE)file ))!=0 )return ret;
- return -1;
-}
-
-SQInteger file_write(SQUserPointer file,SQUserPointer p,SQInteger size)
-{
- return sqstd_fwrite(p,1,size,(SQFILE)file);
-}
-
-SQRESULT sqstd_loadfile(HSQUIRRELVM v,const SQChar *filename,SQBool printerror)
-{
- SQFILE file = sqstd_fopen(filename,_SC("rb"));
- SQInteger ret;
- unsigned short us;
- unsigned char uc;
- SQLEXREADFUNC func = _io_file_lexfeed_ASCII;
- if(file){
- ret = sqstd_fread(&us,1,2,file);
- if(ret != 2) {
- //probably an empty file
- us = 0;
- }
- if(us == SQ_BYTECODE_STREAM_TAG) { //BYTECODE
- sqstd_fseek(file,0,SQ_SEEK_SET);
- if(SQ_SUCCEEDED(sq_readclosure(v,file_read,file))) {
- sqstd_fclose(file);
- return SQ_OK;
- }
- }
- else { //SCRIPT
- switch(us)
- {
- //gotta swap the next 2 lines on BIG endian machines
- case 0xFFFE: func = _io_file_lexfeed_UCS2_BE; break;//UTF-16 little endian;
- case 0xFEFF: func = _io_file_lexfeed_UCS2_LE; break;//UTF-16 big endian;
- case 0xBBEF:
- if(sqstd_fread(&uc,1,sizeof(uc),file) == 0) {
- sqstd_fclose(file);
- return sq_throwerror(v,_SC("io error"));
- }
- if(uc != 0xBF) {
- sqstd_fclose(file);
- return sq_throwerror(v,_SC("Unrecognozed ecoding"));
- }
- func = _io_file_lexfeed_UTF8;
- break;//UTF-8 ;
- default: sqstd_fseek(file,0,SQ_SEEK_SET); break; // ascii
- }
-
- if(SQ_SUCCEEDED(sq_compile(v,func,file,filename,printerror))){
- sqstd_fclose(file);
- return SQ_OK;
- }
- }
- sqstd_fclose(file);
- return SQ_ERROR;
- }
- return sq_throwerror(v,_SC("cannot open the file"));
-}
-
-SQRESULT sqstd_dofile(HSQUIRRELVM v,const SQChar *filename,SQBool retval,SQBool printerror)
-{
- if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror))) {
- sq_push(v,-2);
- if(SQ_SUCCEEDED(sq_call(v,1,retval,SQTrue))) {
- sq_remove(v,retval?-2:-1); //removes the closure
- return 1;
- }
- sq_pop(v,1); //removes the closure
- }
- return SQ_ERROR;
-}
-
-SQRESULT sqstd_writeclosuretofile(HSQUIRRELVM v,const SQChar *filename)
-{
- SQFILE file = sqstd_fopen(filename,_SC("wb+"));
- if(!file) return sq_throwerror(v,_SC("cannot open the file"));
- if(SQ_SUCCEEDED(sq_writeclosure(v,file_write,file))) {
- sqstd_fclose(file);
- return SQ_OK;
- }
- sqstd_fclose(file);
- return SQ_ERROR; //forward the error
-}
-
-SQInteger _g_io_loadfile(HSQUIRRELVM v)
-{
- const SQChar *filename;
- SQBool printerror = SQFalse;
- sq_getstring(v,2,&filename);
- if(sq_gettop(v) >= 3) {
- sq_getbool(v,3,&printerror);
- }
- if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror)))
- return 1;
- return SQ_ERROR; //propagates the error
-}
-
-SQInteger _g_io_writeclosuretofile(HSQUIRRELVM v)
-{
- const SQChar *filename;
- sq_getstring(v,2,&filename);
- if(SQ_SUCCEEDED(sqstd_writeclosuretofile(v,filename)))
- return 1;
- return SQ_ERROR; //propagates the error
-}
-
-SQInteger _g_io_dofile(HSQUIRRELVM v)
-{
- const SQChar *filename;
- SQBool printerror = SQFalse;
- sq_getstring(v,2,&filename);
- if(sq_gettop(v) >= 3) {
- sq_getbool(v,3,&printerror);
- }
- sq_push(v,1); //repush the this
- if(SQ_SUCCEEDED(sqstd_dofile(v,filename,SQTrue,printerror)))
- return 1;
- return SQ_ERROR; //propagates the error
-}
-
-#define _DECL_GLOBALIO_FUNC(name,nparams,typecheck) {_SC(#name),_g_io_##name,nparams,typecheck}
-static SQRegFunction iolib_funcs[]={
- _DECL_GLOBALIO_FUNC(loadfile,-2,_SC(".sb")),
- _DECL_GLOBALIO_FUNC(dofile,-2,_SC(".sb")),
- _DECL_GLOBALIO_FUNC(writeclosuretofile,3,_SC(".sc")),
- {0,0}
-};
-
-SQRESULT sqstd_register_iolib(HSQUIRRELVM v)
-{
- SQInteger top = sq_gettop(v);
- //create delegate
- declare_stream(v,_SC("file"),(SQUserPointer)SQSTD_FILE_TYPE_TAG,_SC("std_file"),_file_methods,iolib_funcs);
- sq_pushstring(v,_SC("stdout"),-1);
- sqstd_createfile(v,stdout,SQFalse);
- sq_createslot(v,-3);
- sq_pushstring(v,_SC("stdin"),-1);
- sqstd_createfile(v,stdin,SQFalse);
- sq_createslot(v,-3);
- sq_pushstring(v,_SC("stderr"),-1);
- sqstd_createfile(v,stderr,SQFalse);
- sq_createslot(v,-3);
- sq_settop(v,top);
- return SQ_OK;
-}
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#include <squirrel.h>
-#include <math.h>
-#include <stdlib.h>
-#include <sqstdmath.h>
-
-#define SINGLE_ARG_FUNC(_funcname) static SQInteger math_##_funcname(HSQUIRRELVM v){ \
- SQFloat f; \
- sq_getfloat(v,2,&f); \
- sq_pushfloat(v,(SQFloat)_funcname(f)); \
- return 1; \
-}
-
-#define TWO_ARGS_FUNC(_funcname) static SQInteger math_##_funcname(HSQUIRRELVM v){ \
- SQFloat p1,p2; \
- sq_getfloat(v,2,&p1); \
- sq_getfloat(v,3,&p2); \
- sq_pushfloat(v,(SQFloat)_funcname(p1,p2)); \
- return 1; \
-}
-
-static SQInteger math_srand(HSQUIRRELVM v)
-{
- SQInteger i;
- if(SQ_FAILED(sq_getinteger(v,2,&i)))
- return sq_throwerror(v,_SC("invalid param"));
- srand((unsigned int)i);
- return 0;
-}
-
-static SQInteger math_rand(HSQUIRRELVM v)
-{
- sq_pushinteger(v,rand());
- return 1;
-}
-
-static SQInteger math_abs(HSQUIRRELVM v)
-{
- SQInteger n;
- sq_getinteger(v,2,&n);
- sq_pushinteger(v,(SQInteger)abs((int)n));
- return 1;
-}
-
-SINGLE_ARG_FUNC(sqrt)
-SINGLE_ARG_FUNC(fabs)
-SINGLE_ARG_FUNC(sin)
-SINGLE_ARG_FUNC(cos)
-SINGLE_ARG_FUNC(asin)
-SINGLE_ARG_FUNC(acos)
-SINGLE_ARG_FUNC(log)
-SINGLE_ARG_FUNC(log10)
-SINGLE_ARG_FUNC(tan)
-SINGLE_ARG_FUNC(atan)
-TWO_ARGS_FUNC(atan2)
-TWO_ARGS_FUNC(pow)
-SINGLE_ARG_FUNC(floor)
-SINGLE_ARG_FUNC(ceil)
-SINGLE_ARG_FUNC(exp)
-
-#define _DECL_FUNC(name,nparams,tycheck) {_SC(#name),math_##name,nparams,tycheck}
-static SQRegFunction mathlib_funcs[] = {
- _DECL_FUNC(sqrt,2,_SC(".n")),
- _DECL_FUNC(sin,2,_SC(".n")),
- _DECL_FUNC(cos,2,_SC(".n")),
- _DECL_FUNC(asin,2,_SC(".n")),
- _DECL_FUNC(acos,2,_SC(".n")),
- _DECL_FUNC(log,2,_SC(".n")),
- _DECL_FUNC(log10,2,_SC(".n")),
- _DECL_FUNC(tan,2,_SC(".n")),
- _DECL_FUNC(atan,2,_SC(".n")),
- _DECL_FUNC(atan2,3,_SC(".nn")),
- _DECL_FUNC(pow,3,_SC(".nn")),
- _DECL_FUNC(floor,2,_SC(".n")),
- _DECL_FUNC(ceil,2,_SC(".n")),
- _DECL_FUNC(exp,2,_SC(".n")),
- _DECL_FUNC(srand,2,_SC(".n")),
- _DECL_FUNC(rand,1,NULL),
- _DECL_FUNC(fabs,2,_SC(".n")),
- _DECL_FUNC(abs,2,_SC(".n")),
- {0,0},
-};
-
-#ifndef M_PI
-#define M_PI (3.14159265358979323846)
-#endif
-
-SQRESULT sqstd_register_mathlib(HSQUIRRELVM v)
-{
- SQInteger i=0;
- while(mathlib_funcs[i].name!=0) {
- sq_pushstring(v,mathlib_funcs[i].name,-1);
- sq_newclosure(v,mathlib_funcs[i].f,0);
- sq_setparamscheck(v,mathlib_funcs[i].nparamscheck,mathlib_funcs[i].typemask);
- sq_setnativeclosurename(v,-1,mathlib_funcs[i].name);
- sq_createslot(v,-3);
- i++;
- }
- sq_pushstring(v,_SC("RAND_MAX"),-1);
- sq_pushinteger(v,RAND_MAX);
- sq_createslot(v,-3);
- sq_pushstring(v,_SC("PI"),-1);
- sq_pushfloat(v,(SQFloat)M_PI);
- sq_createslot(v,-3);
- return SQ_OK;
-}
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#include <squirrel.h>
-#include <string.h>
-#include <ctype.h>
-#include <setjmp.h>
-#include "sqstdstring.h"
-
-#ifdef _UINCODE
-#define scisprint iswprint
-#else
-#define scisprint isprint
-#endif
-
-#ifdef _DEBUG
-#include <stdio.h>
-
-static const SQChar *g_nnames[] =
-{
- _SC("NONE"),_SC("OP_GREEDY"), _SC("OP_OR"),
- _SC("OP_EXPR"),_SC("OP_NOCAPEXPR"),_SC("OP_DOT"), _SC("OP_CLASS"),
- _SC("OP_CCLASS"),_SC("OP_NCLASS"),_SC("OP_RANGE"),_SC("OP_CHAR"),
- _SC("OP_EOL"),_SC("OP_BOL"),_SC("OP_WB")
-};
-
-#endif
-
-#define OP_GREEDY (MAX_CHAR+1) // * + ? {n}
-#define OP_OR (MAX_CHAR+2)
-#define OP_EXPR (MAX_CHAR+3) //parentesis ()
-#define OP_NOCAPEXPR (MAX_CHAR+4) //parentesis (?:)
-#define OP_DOT (MAX_CHAR+5)
-#define OP_CLASS (MAX_CHAR+6)
-#define OP_CCLASS (MAX_CHAR+7)
-#define OP_NCLASS (MAX_CHAR+8) //negates class the [^
-#define OP_RANGE (MAX_CHAR+9)
-#define OP_CHAR (MAX_CHAR+10)
-#define OP_EOL (MAX_CHAR+11)
-#define OP_BOL (MAX_CHAR+12)
-#define OP_WB (MAX_CHAR+13)
-
-#define SQREX_SYMBOL_ANY_CHAR ('.')
-#define SQREX_SYMBOL_GREEDY_ONE_OR_MORE ('+')
-#define SQREX_SYMBOL_GREEDY_ZERO_OR_MORE ('*')
-#define SQREX_SYMBOL_GREEDY_ZERO_OR_ONE ('?')
-#define SQREX_SYMBOL_BRANCH ('|')
-#define SQREX_SYMBOL_END_OF_STRING ('$')
-#define SQREX_SYMBOL_BEGINNING_OF_STRING ('^')
-#define SQREX_SYMBOL_ESCAPE_CHAR ('\\')
-
-
-typedef int SQRexNodeType;
-
-typedef struct tagSQRexNode{
- SQRexNodeType type;
- SQInteger left;
- SQInteger right;
- SQInteger next;
-}SQRexNode;
-
-struct SQRex{
- const SQChar *_eol;
- const SQChar *_bol;
- const SQChar *_p;
- SQInteger _first;
- SQInteger _op;
- SQRexNode *_nodes;
- SQInteger _nallocated;
- SQInteger _nsize;
- SQInteger _nsubexpr;
- SQRexMatch *_matches;
- SQInteger _currsubexp;
- void *_jmpbuf;
- const SQChar **_error;
-};
-
-static SQInteger sqstd_rex_list(SQRex *exp);
-
-static SQInteger sqstd_rex_newnode(SQRex *exp, SQRexNodeType type)
-{
- SQRexNode n;
- n.type = type;
- n.next = n.right = n.left = -1;
- if(type == OP_EXPR)
- n.right = exp->_nsubexpr++;
- if(exp->_nallocated < (exp->_nsize + 1)) {
- SQInteger oldsize = exp->_nallocated;
- exp->_nallocated *= 2;
- exp->_nodes = (SQRexNode *)sq_realloc(exp->_nodes, oldsize * sizeof(SQRexNode) ,exp->_nallocated * sizeof(SQRexNode));
- }
- exp->_nodes[exp->_nsize++] = n;
- SQInteger newid = exp->_nsize - 1;
- return (SQInteger)newid;
-}
-
-static void sqstd_rex_error(SQRex *exp,const SQChar *error)
-{
- if(exp->_error) *exp->_error = error;
- longjmp(*((jmp_buf*)exp->_jmpbuf),-1);
-}
-
-static void sqstd_rex_expect(SQRex *exp, SQInteger n){
- if((*exp->_p) != n)
- sqstd_rex_error(exp, _SC("expected paren"));
- exp->_p++;
-}
-
-static SQChar sqstd_rex_escapechar(SQRex *exp)
-{
- if(*exp->_p == SQREX_SYMBOL_ESCAPE_CHAR){
- exp->_p++;
- switch(*exp->_p) {
- case 'v': exp->_p++; return '\v';
- case 'n': exp->_p++; return '\n';
- case 't': exp->_p++; return '\t';
- case 'r': exp->_p++; return '\r';
- case 'f': exp->_p++; return '\f';
- default: return (*exp->_p++);
- }
- } else if(!scisprint(*exp->_p)) sqstd_rex_error(exp,_SC("letter expected"));
- return (*exp->_p++);
-}
-
-static SQInteger sqstd_rex_charclass(SQRex *exp,SQInteger classid)
-{
- SQInteger n = sqstd_rex_newnode(exp,OP_CCLASS);
- exp->_nodes[n].left = classid;
- return n;
-}
-
-static SQInteger sqstd_rex_charnode(SQRex *exp,SQBool isclass)
-{
- SQChar t;
- if(*exp->_p == SQREX_SYMBOL_ESCAPE_CHAR) {
- exp->_p++;
- switch(*exp->_p) {
- case 'n': exp->_p++; return sqstd_rex_newnode(exp,'\n');
- case 't': exp->_p++; return sqstd_rex_newnode(exp,'\t');
- case 'r': exp->_p++; return sqstd_rex_newnode(exp,'\r');
- case 'f': exp->_p++; return sqstd_rex_newnode(exp,'\f');
- case 'v': exp->_p++; return sqstd_rex_newnode(exp,'\v');
- case 'a': case 'A': case 'w': case 'W': case 's': case 'S':
- case 'd': case 'D': case 'x': case 'X': case 'c': case 'C':
- case 'p': case 'P': case 'l': case 'u':
- {
- t = *exp->_p; exp->_p++;
- return sqstd_rex_charclass(exp,t);
- }
- case 'b':
- case 'B':
- if(!isclass) {
- SQInteger node = sqstd_rex_newnode(exp,OP_WB);
- exp->_nodes[node].left = *exp->_p;
- exp->_p++;
- return node;
- } //else default
- default:
- t = *exp->_p; exp->_p++;
- return sqstd_rex_newnode(exp,t);
- }
- }
- else if(!scisprint(*exp->_p)) {
-
- sqstd_rex_error(exp,_SC("letter expected"));
- }
- t = *exp->_p; exp->_p++;
- return sqstd_rex_newnode(exp,t);
-}
-static SQInteger sqstd_rex_class(SQRex *exp)
-{
- SQInteger ret = -1;
- SQInteger first = -1,chain;
- if(*exp->_p == SQREX_SYMBOL_BEGINNING_OF_STRING){
- ret = sqstd_rex_newnode(exp,OP_NCLASS);
- exp->_p++;
- }else ret = sqstd_rex_newnode(exp,OP_CLASS);
-
- if(*exp->_p == ']') sqstd_rex_error(exp,_SC("empty class"));
- chain = ret;
- while(*exp->_p != ']' && exp->_p != exp->_eol) {
- if(*exp->_p == '-' && first != -1){
- SQInteger r;
- if(*exp->_p++ == ']') sqstd_rex_error(exp,_SC("unfinished range"));
- r = sqstd_rex_newnode(exp,OP_RANGE);
- if(first>*exp->_p) sqstd_rex_error(exp,_SC("invalid range"));
- if(exp->_nodes[first].type == OP_CCLASS) sqstd_rex_error(exp,_SC("cannot use character classes in ranges"));
- exp->_nodes[r].left = exp->_nodes[first].type;
- SQInteger t = sqstd_rex_escapechar(exp);
- exp->_nodes[r].right = t;
- exp->_nodes[chain].next = r;
- chain = r;
- first = -1;
- }
- else{
- if(first!=-1){
- SQInteger c = first;
- exp->_nodes[chain].next = c;
- chain = c;
- first = sqstd_rex_charnode(exp,SQTrue);
- }
- else{
- first = sqstd_rex_charnode(exp,SQTrue);
- }
- }
- }
- if(first!=-1){
- SQInteger c = first;
- exp->_nodes[chain].next = c;
- chain = c;
- first = -1;
- }
- /* hack? */
- exp->_nodes[ret].left = exp->_nodes[ret].next;
- exp->_nodes[ret].next = -1;
- return ret;
-}
-
-static SQInteger sqstd_rex_parsenumber(SQRex *exp)
-{
- SQInteger ret = *exp->_p-'0';
- SQInteger positions = 10;
- exp->_p++;
- while(isdigit(*exp->_p)) {
- ret = ret*10+(*exp->_p++-'0');
- if(positions==1000000000) sqstd_rex_error(exp,_SC("overflow in numeric constant"));
- positions *= 10;
- };
- return ret;
-}
-
-static SQInteger sqstd_rex_element(SQRex *exp)
-{
- SQInteger ret = -1;
- switch(*exp->_p)
- {
- case '(': {
- SQInteger expr;
- exp->_p++;
-
-
- if(*exp->_p =='?') {
- exp->_p++;
- sqstd_rex_expect(exp,':');
- expr = sqstd_rex_newnode(exp,OP_NOCAPEXPR);
- }
- else
- expr = sqstd_rex_newnode(exp,OP_EXPR);
- SQInteger newn = sqstd_rex_list(exp);
- exp->_nodes[expr].left = newn;
- ret = expr;
- sqstd_rex_expect(exp,')');
- }
- break;
- case '[':
- exp->_p++;
- ret = sqstd_rex_class(exp);
- sqstd_rex_expect(exp,']');
- break;
- case SQREX_SYMBOL_END_OF_STRING: exp->_p++; ret = sqstd_rex_newnode(exp,OP_EOL);break;
- case SQREX_SYMBOL_ANY_CHAR: exp->_p++; ret = sqstd_rex_newnode(exp,OP_DOT);break;
- default:
- ret = sqstd_rex_charnode(exp,SQFalse);
- break;
- }
-
-
- SQInteger op;
- SQBool isgreedy = SQFalse;
- unsigned short p0 = 0, p1 = 0;
- switch(*exp->_p){
- case SQREX_SYMBOL_GREEDY_ZERO_OR_MORE: p0 = 0; p1 = 0xFFFF; exp->_p++; isgreedy = SQTrue; break;
- case SQREX_SYMBOL_GREEDY_ONE_OR_MORE: p0 = 1; p1 = 0xFFFF; exp->_p++; isgreedy = SQTrue; break;
- case SQREX_SYMBOL_GREEDY_ZERO_OR_ONE: p0 = 0; p1 = 1; exp->_p++; isgreedy = SQTrue; break;
- case '{':
- exp->_p++;
- if(!isdigit(*exp->_p)) sqstd_rex_error(exp,_SC("number expected"));
- p0 = (unsigned short)sqstd_rex_parsenumber(exp);
- /*******************************/
- switch(*exp->_p) {
- case '}':
- p1 = p0; exp->_p++;
- break;
- case ',':
- exp->_p++;
- p1 = 0xFFFF;
- if(isdigit(*exp->_p)){
- p1 = (unsigned short)sqstd_rex_parsenumber(exp);
- }
- sqstd_rex_expect(exp,'}');
- break;
- default:
- sqstd_rex_error(exp,_SC(", or } expected"));
- }
- /*******************************/
- isgreedy = SQTrue;
- break;
-
- }
- if(isgreedy) {
- SQInteger nnode = sqstd_rex_newnode(exp,OP_GREEDY);
- op = OP_GREEDY;
- exp->_nodes[nnode].left = ret;
- exp->_nodes[nnode].right = ((p0)<<16)|p1;
- ret = nnode;
- }
-
- if((*exp->_p != SQREX_SYMBOL_BRANCH) && (*exp->_p != ')') && (*exp->_p != SQREX_SYMBOL_GREEDY_ZERO_OR_MORE) && (*exp->_p != SQREX_SYMBOL_GREEDY_ONE_OR_MORE) && (*exp->_p != '\0')) {
- SQInteger nnode = sqstd_rex_element(exp);
- exp->_nodes[ret].next = nnode;
- }
-
- return ret;
-}
-
-static SQInteger sqstd_rex_list(SQRex *exp)
-{
- SQInteger ret=-1,e;
- if(*exp->_p == SQREX_SYMBOL_BEGINNING_OF_STRING) {
- exp->_p++;
- ret = sqstd_rex_newnode(exp,OP_BOL);
- }
- e = sqstd_rex_element(exp);
- if(ret != -1) {
- exp->_nodes[ret].next = e;
- }
- else ret = e;
-
- if(*exp->_p == SQREX_SYMBOL_BRANCH) {
- SQInteger temp,tright;
- exp->_p++;
- temp = sqstd_rex_newnode(exp,OP_OR);
- exp->_nodes[temp].left = ret;
- tright = sqstd_rex_list(exp);
- exp->_nodes[temp].right = tright;
- ret = temp;
- }
- return ret;
-}
-
-static SQBool sqstd_rex_matchcclass(SQInteger cclass,SQChar c)
-{
- switch(cclass) {
- case 'a': return isalpha(c)?SQTrue:SQFalse;
- case 'A': return !isalpha(c)?SQTrue:SQFalse;
- case 'w': return (isalnum(c) || c == '_')?SQTrue:SQFalse;
- case 'W': return (!isalnum(c) && c != '_')?SQTrue:SQFalse;
- case 's': return isspace(c)?SQTrue:SQFalse;
- case 'S': return !isspace(c)?SQTrue:SQFalse;
- case 'd': return isdigit(c)?SQTrue:SQFalse;
- case 'D': return !isdigit(c)?SQTrue:SQFalse;
- case 'x': return isxdigit(c)?SQTrue:SQFalse;
- case 'X': return !isxdigit(c)?SQTrue:SQFalse;
- case 'c': return iscntrl(c)?SQTrue:SQFalse;
- case 'C': return !iscntrl(c)?SQTrue:SQFalse;
- case 'p': return ispunct(c)?SQTrue:SQFalse;
- case 'P': return !ispunct(c)?SQTrue:SQFalse;
- case 'l': return islower(c)?SQTrue:SQFalse;
- case 'u': return isupper(c)?SQTrue:SQFalse;
- }
- return SQFalse; /*cannot happen*/
-}
-
-static SQBool sqstd_rex_matchclass(SQRex* exp,SQRexNode *node,SQChar c)
-{
- do {
- switch(node->type) {
- case OP_RANGE:
- if(c >= node->left && c <= node->right) return SQTrue;
- break;
- case OP_CCLASS:
- if(sqstd_rex_matchcclass(node->left,c)) return SQTrue;
- break;
- default:
- if(c == node->type)return SQTrue;
- }
- } while((node->next != -1) && (node = &exp->_nodes[node->next]));
- return SQFalse;
-}
-
-static const SQChar *sqstd_rex_matchnode(SQRex* exp,SQRexNode *node,const SQChar *str,SQRexNode *next)
-{
-
- SQRexNodeType type = node->type;
- switch(type) {
- case OP_GREEDY: {
- //SQRexNode *greedystop = (node->next != -1) ? &exp->_nodes[node->next] : NULL;
- SQRexNode *greedystop = NULL;
- SQInteger p0 = (node->right >> 16)&0x0000FFFF, p1 = node->right&0x0000FFFF, nmaches = 0;
- const SQChar *s=str, *good = str;
-
- if(node->next != -1) {
- greedystop = &exp->_nodes[node->next];
- }
- else {
- greedystop = next;
- }
-
- while((nmaches == 0xFFFF || nmaches < p1)) {
-
- const SQChar *stop;
- if(!(s = sqstd_rex_matchnode(exp,&exp->_nodes[node->left],s,greedystop)))
- break;
- nmaches++;
- good=s;
- if(greedystop) {
- //checks that 0 matches satisfy the expression(if so skips)
- //if not would always stop(for instance if is a '?')
- if(greedystop->type != OP_GREEDY ||
- (greedystop->type == OP_GREEDY && ((greedystop->right >> 16)&0x0000FFFF) != 0))
- {
- SQRexNode *gnext = NULL;
- if(greedystop->next != -1) {
- gnext = &exp->_nodes[greedystop->next];
- }else if(next && next->next != -1){
- gnext = &exp->_nodes[next->next];
- }
- stop = sqstd_rex_matchnode(exp,greedystop,s,gnext);
- if(stop) {
- //if satisfied stop it
- if(p0 == p1 && p0 == nmaches) break;
- else if(nmaches >= p0 && p1 == 0xFFFF) break;
- else if(nmaches >= p0 && nmaches <= p1) break;
- }
- }
- }
-
- if(s >= exp->_eol)
- break;
- }
- if(p0 == p1 && p0 == nmaches) return good;
- else if(nmaches >= p0 && p1 == 0xFFFF) return good;
- else if(nmaches >= p0 && nmaches <= p1) return good;
- return NULL;
- }
- case OP_OR: {
- const SQChar *asd = str;
- SQRexNode *temp=&exp->_nodes[node->left];
- while( (asd = sqstd_rex_matchnode(exp,temp,asd,NULL)) ) {
- if(temp->next != -1)
- temp = &exp->_nodes[temp->next];
- else
- return asd;
- }
- asd = str;
- temp = &exp->_nodes[node->right];
- while( (asd = sqstd_rex_matchnode(exp,temp,asd,NULL)) ) {
- if(temp->next != -1)
- temp = &exp->_nodes[temp->next];
- else
- return asd;
- }
- return NULL;
- break;
- }
- case OP_EXPR:
- case OP_NOCAPEXPR:{
- SQRexNode *n = &exp->_nodes[node->left];
- const SQChar *cur = str;
- SQInteger capture = -1;
- if(node->type != OP_NOCAPEXPR && node->right == exp->_currsubexp) {
- capture = exp->_currsubexp;
- exp->_matches[capture].begin = cur;
- exp->_currsubexp++;
- }
-
- do {
- SQRexNode *subnext = NULL;
- if(n->next != -1) {
- subnext = &exp->_nodes[n->next];
- }else {
- subnext = next;
- }
- if(!(cur = sqstd_rex_matchnode(exp,n,cur,subnext))) {
- if(capture != -1){
- exp->_matches[capture].begin = 0;
- exp->_matches[capture].len = 0;
- }
- return NULL;
- }
- } while((n->next != -1) && (n = &exp->_nodes[n->next]));
-
- if(capture != -1)
- exp->_matches[capture].len = cur - exp->_matches[capture].begin;
- return cur;
- }
- case OP_WB:
- if(str == exp->_bol && !isspace(*str)
- || (str == exp->_eol && !isspace(*(str-1)))
- || (!isspace(*str) && isspace(*(str+1)))
- || (isspace(*str) && !isspace(*(str+1))) ) {
- return (node->left == 'b')?str:NULL;
- }
- return (node->left == 'b')?NULL:str;
- case OP_BOL:
- if(str == exp->_bol) return str;
- return NULL;
- case OP_EOL:
- if(str == exp->_eol) return str;
- return NULL;
- case OP_DOT:{
- *str++;
- }
- return str;
- case OP_NCLASS:
- case OP_CLASS:
- if(sqstd_rex_matchclass(exp,&exp->_nodes[node->left],*str)?(type == OP_CLASS?SQTrue:SQFalse):(type == OP_NCLASS?SQTrue:SQFalse)) {
- *str++;
- return str;
- }
- return NULL;
- case OP_CCLASS:
- if(sqstd_rex_matchcclass(node->left,*str)) {
- *str++;
- return str;
- }
- return NULL;
- default: /* char */
- if(*str != node->type) return NULL;
- *str++;
- return str;
- }
- return NULL;
-}
-
-/* public api */
-SQRex *sqstd_rex_compile(const SQChar *pattern,const SQChar **error)
-{
- SQRex *exp = (SQRex *)sq_malloc(sizeof(SQRex));
- exp->_eol = exp->_bol = NULL;
- exp->_p = pattern;
- exp->_nallocated = (SQInteger)scstrlen(pattern) * sizeof(SQChar);
- exp->_nodes = (SQRexNode *)sq_malloc(exp->_nallocated * sizeof(SQRexNode));
- exp->_nsize = 0;
- exp->_matches = 0;
- exp->_nsubexpr = 0;
- exp->_first = sqstd_rex_newnode(exp,OP_EXPR);
- exp->_error = error;
- exp->_jmpbuf = sq_malloc(sizeof(jmp_buf));
- if(setjmp(*((jmp_buf*)exp->_jmpbuf)) == 0) {
- SQInteger res = sqstd_rex_list(exp);
- exp->_nodes[exp->_first].left = res;
- if(*exp->_p!='\0')
- sqstd_rex_error(exp,_SC("unexpected character"));
-#ifdef _DEBUG
- {
- SQInteger nsize,i;
- SQRexNode *t;
- nsize = exp->_nsize;
- t = &exp->_nodes[0];
- scprintf(_SC("\n"));
- for(i = 0;i < nsize; i++) {
- if(exp->_nodes[i].type>MAX_CHAR)
- scprintf(_SC("[%02d] %10s "),i,g_nnames[exp->_nodes[i].type-MAX_CHAR]);
- else
- scprintf(_SC("[%02d] %10c "),i,exp->_nodes[i].type);
- scprintf(_SC("left %02d right %02d next %02d\n"),exp->_nodes[i].left,exp->_nodes[i].right,exp->_nodes[i].next);
- }
- scprintf(_SC("\n"));
- }
-#endif
- exp->_matches = (SQRexMatch *) sq_malloc(exp->_nsubexpr * sizeof(SQRexMatch));
- memset(exp->_matches,0,exp->_nsubexpr * sizeof(SQRexMatch));
- }
- else{
- sqstd_rex_free(exp);
- return NULL;
- }
- return exp;
-}
-
-void sqstd_rex_free(SQRex *exp)
-{
- if(exp) {
- if(exp->_nodes) sq_free(exp->_nodes,exp->_nallocated * sizeof(SQRexNode));
- if(exp->_jmpbuf) sq_free(exp->_jmpbuf,sizeof(jmp_buf));
- if(exp->_matches) sq_free(exp->_matches,exp->_nsubexpr * sizeof(SQRexMatch));
- sq_free(exp,sizeof(SQRex));
- }
-}
-
-SQBool sqstd_rex_match(SQRex* exp,const SQChar* text)
-{
- const SQChar* res = NULL;
- exp->_bol = text;
- exp->_eol = text + scstrlen(text);
- exp->_currsubexp = 0;
- res = sqstd_rex_matchnode(exp,exp->_nodes,text,NULL);
- if(res == NULL || res != exp->_eol)
- return SQFalse;
- return SQTrue;
-}
-
-SQBool sqstd_rex_searchrange(SQRex* exp,const SQChar* text_begin,const SQChar* text_end,const SQChar** out_begin, const SQChar** out_end)
-{
- const SQChar *cur = NULL;
- SQInteger node = exp->_first;
- if(text_begin >= text_end) return SQFalse;
- exp->_bol = text_begin;
- exp->_eol = text_end;
- do {
- cur = text_begin;
- while(node != -1) {
- exp->_currsubexp = 0;
- cur = sqstd_rex_matchnode(exp,&exp->_nodes[node],cur,NULL);
- if(!cur)
- break;
- node = exp->_nodes[node].next;
- }
- *text_begin++;
- } while(cur == NULL && text_begin != text_end);
-
- if(cur == NULL)
- return SQFalse;
-
- --text_begin;
-
- if(out_begin) *out_begin = text_begin;
- if(out_end) *out_end = cur;
- return SQTrue;
-}
-
-SQBool sqstd_rex_search(SQRex* exp,const SQChar* text, const SQChar** out_begin, const SQChar** out_end)
-{
- return sqstd_rex_searchrange(exp,text,text + scstrlen(text),out_begin,out_end);
-}
-
-SQInteger sqstd_rex_getsubexpcount(SQRex* exp)
-{
- return exp->_nsubexpr;
-}
-
-SQBool sqstd_rex_getsubexp(SQRex* exp, SQInteger n, SQRexMatch *subexp)
-{
- if( n<0 || n >= exp->_nsubexpr) return SQFalse;
- *subexp = exp->_matches[n];
- return SQTrue;
-}
-
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#include <new>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <squirrel.h>
-#include <sqstdio.h>
-#include <sqstdblob.h>
-#include "sqstdstream.h"
-#include "sqstdblobimpl.h"
-
-#define SETUP_STREAM(v) \
- SQStream *self = NULL; \
- if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_STREAM_TYPE_TAG))) \
- return sq_throwerror(v,_SC("invalid type tag")); \
- if(!self->IsValid()) \
- return sq_throwerror(v,_SC("the stream is invalid"));
-
-SQInteger _stream_readblob(HSQUIRRELVM v)
-{
- SETUP_STREAM(v);
- SQUserPointer data,blobp;
- SQInteger size,res;
- sq_getinteger(v,2,&size);
- if(size > self->Len()) {
- size = self->Len();
- }
- data = sq_getscratchpad(v,size);
- res = self->Read(data,size);
- if(res <= 0)
- return sq_throwerror(v,_SC("no data left to read"));
- blobp = sqstd_createblob(v,res);
- memcpy(blobp,data,res);
- return 1;
-}
-
-#define SAFE_READN(ptr,len) { \
- if(self->Read(ptr,len) != len) return sq_throwerror(v,_SC("io error")); \
- }
-SQInteger _stream_readn(HSQUIRRELVM v)
-{
- SETUP_STREAM(v);
- SQInteger format;
- sq_getinteger(v, 2, &format);
- switch(format) {
- case 'l': {
- SQInteger i;
- SAFE_READN(&i, sizeof(i));
- sq_pushinteger(v, i);
- }
- break;
- case 'i': {
- SQInt32 i;
- SAFE_READN(&i, sizeof(i));
- sq_pushinteger(v, i);
- }
- break;
- case 's': {
- short s;
- SAFE_READN(&s, sizeof(short));
- sq_pushinteger(v, s);
- }
- break;
- case 'w': {
- unsigned short w;
- SAFE_READN(&w, sizeof(unsigned short));
- sq_pushinteger(v, w);
- }
- break;
- case 'c': {
- char c;
- SAFE_READN(&c, sizeof(char));
- sq_pushinteger(v, c);
- }
- break;
- case 'b': {
- unsigned char c;
- SAFE_READN(&c, sizeof(unsigned char));
- sq_pushinteger(v, c);
- }
- break;
- case 'f': {
- float f;
- SAFE_READN(&f, sizeof(float));
- sq_pushfloat(v, f);
- }
- break;
- case 'd': {
- double d;
- SAFE_READN(&d, sizeof(double));
- sq_pushfloat(v, (SQFloat)d);
- }
- break;
- default:
- return sq_throwerror(v, _SC("invalid format"));
- }
- return 1;
-}
-
-SQInteger _stream_writeblob(HSQUIRRELVM v)
-{
- SQUserPointer data;
- SQInteger size;
- SETUP_STREAM(v);
- if(SQ_FAILED(sqstd_getblob(v,2,&data)))
- return sq_throwerror(v,_SC("invalid parameter"));
- size = sqstd_getblobsize(v,2);
- if(self->Write(data,size) != size)
- return sq_throwerror(v,_SC("io error"));
- sq_pushinteger(v,size);
- return 1;
-}
-
-SQInteger _stream_writen(HSQUIRRELVM v)
-{
- SETUP_STREAM(v);
- SQInteger format, ti;
- SQFloat tf;
- sq_getinteger(v, 3, &format);
- switch(format) {
- case 'l': {
- SQInteger i;
- sq_getinteger(v, 2, &ti);
- i = ti;
- self->Write(&i, sizeof(SQInteger));
- }
- break;
- case 'i': {
- SQInt32 i;
- sq_getinteger(v, 2, &ti);
- i = (SQInt32)ti;
- self->Write(&i, sizeof(SQInt32));
- }
- break;
- case 's': {
- short s;
- sq_getinteger(v, 2, &ti);
- s = (short)ti;
- self->Write(&s, sizeof(short));
- }
- break;
- case 'w': {
- unsigned short w;
- sq_getinteger(v, 2, &ti);
- w = (unsigned short)ti;
- self->Write(&w, sizeof(unsigned short));
- }
- break;
- case 'c': {
- char c;
- sq_getinteger(v, 2, &ti);
- c = (char)ti;
- self->Write(&c, sizeof(char));
- }
- break;
- case 'b': {
- unsigned char b;
- sq_getinteger(v, 2, &ti);
- b = (unsigned char)ti;
- self->Write(&b, sizeof(unsigned char));
- }
- break;
- case 'f': {
- float f;
- sq_getfloat(v, 2, &tf);
- f = (float)tf;
- self->Write(&f, sizeof(float));
- }
- break;
- case 'd': {
- double d;
- sq_getfloat(v, 2, &tf);
- d = tf;
- self->Write(&d, sizeof(double));
- }
- break;
- default:
- return sq_throwerror(v, _SC("invalid format"));
- }
- return 0;
-}
-
-SQInteger _stream_seek(HSQUIRRELVM v)
-{
- SETUP_STREAM(v);
- SQInteger offset, origin = SQ_SEEK_SET;
- sq_getinteger(v, 2, &offset);
- if(sq_gettop(v) > 2) {
- SQInteger t;
- sq_getinteger(v, 3, &t);
- switch(t) {
- case 'b': origin = SQ_SEEK_SET; break;
- case 'c': origin = SQ_SEEK_CUR; break;
- case 'e': origin = SQ_SEEK_END; break;
- default: return sq_throwerror(v,_SC("invalid origin"));
- }
- }
- sq_pushinteger(v, self->Seek(offset, origin));
- return 1;
-}
-
-SQInteger _stream_tell(HSQUIRRELVM v)
-{
- SETUP_STREAM(v);
- sq_pushinteger(v, self->Tell());
- return 1;
-}
-
-SQInteger _stream_len(HSQUIRRELVM v)
-{
- SETUP_STREAM(v);
- sq_pushinteger(v, self->Len());
- return 1;
-}
-
-SQInteger _stream_flush(HSQUIRRELVM v)
-{
- SETUP_STREAM(v);
- if(!self->Flush())
- sq_pushinteger(v, 1);
- else
- sq_pushnull(v);
- return 1;
-}
-
-SQInteger _stream_eos(HSQUIRRELVM v)
-{
- SETUP_STREAM(v);
- if(self->EOS())
- sq_pushinteger(v, 1);
- else
- sq_pushnull(v);
- return 1;
-}
-
-static SQRegFunction _stream_methods[] = {
- _DECL_STREAM_FUNC(readblob,2,_SC("xn")),
- _DECL_STREAM_FUNC(readn,2,_SC("xn")),
- _DECL_STREAM_FUNC(writeblob,-2,_SC("xx")),
- _DECL_STREAM_FUNC(writen,3,_SC("xnn")),
- _DECL_STREAM_FUNC(seek,-2,_SC("xnn")),
- _DECL_STREAM_FUNC(tell,1,_SC("x")),
- _DECL_STREAM_FUNC(len,1,_SC("x")),
- _DECL_STREAM_FUNC(eos,1,_SC("x")),
- _DECL_STREAM_FUNC(flush,1,_SC("x")),
- {0,0}
-};
-
-void init_streamclass(HSQUIRRELVM v)
-{
- sq_pushregistrytable(v);
- sq_pushstring(v,_SC("std_stream"),-1);
- if(SQ_FAILED(sq_get(v,-2))) {
- sq_pushstring(v,_SC("std_stream"),-1);
- sq_newclass(v,SQFalse);
- sq_settypetag(v,-1,(SQUserPointer)SQSTD_STREAM_TYPE_TAG);
- SQInteger i = 0;
- while(_stream_methods[i].name != 0) {
- SQRegFunction &f = _stream_methods[i];
- sq_pushstring(v,f.name,-1);
- sq_newclosure(v,f.f,0);
- sq_setparamscheck(v,f.nparamscheck,f.typemask);
- sq_createslot(v,-3);
- i++;
- }
- sq_createslot(v,-3);
- sq_pushroottable(v);
- sq_pushstring(v,_SC("stream"),-1);
- sq_pushstring(v,_SC("std_stream"),-1);
- sq_get(v,-4);
- sq_createslot(v,-3);
- sq_pop(v,1);
- }
- else {
- sq_pop(v,1); //result
- }
- sq_pop(v,1);
-}
-
-SQRESULT declare_stream(HSQUIRRELVM v,const SQChar* name,SQUserPointer typetag,const SQChar* reg_name,SQRegFunction *methods,SQRegFunction *globals)
-{
- if(sq_gettype(v,-1) != OT_TABLE)
- return sq_throwerror(v,_SC("table expected"));
- SQInteger top = sq_gettop(v);
- //create delegate
- init_streamclass(v);
- sq_pushregistrytable(v);
- sq_pushstring(v,reg_name,-1);
- sq_pushstring(v,_SC("std_stream"),-1);
- if(SQ_SUCCEEDED(sq_get(v,-3))) {
- sq_newclass(v,SQTrue);
- sq_settypetag(v,-1,typetag);
- SQInteger i = 0;
- while(methods[i].name != 0) {
- SQRegFunction &f = methods[i];
- sq_pushstring(v,f.name,-1);
- sq_newclosure(v,f.f,0);
- sq_setparamscheck(v,f.nparamscheck,f.typemask);
- sq_setnativeclosurename(v,-1,f.name);
- sq_createslot(v,-3);
- i++;
- }
- sq_createslot(v,-3);
- sq_pop(v,1);
-
- i = 0;
- while(globals[i].name!=0)
- {
- SQRegFunction &f = globals[i];
- sq_pushstring(v,f.name,-1);
- sq_newclosure(v,f.f,0);
- sq_setparamscheck(v,f.nparamscheck,f.typemask);
- sq_setnativeclosurename(v,-1,f.name);
- sq_createslot(v,-3);
- i++;
- }
- //register the class in the target table
- sq_pushstring(v,name,-1);
- sq_pushregistrytable(v);
- sq_pushstring(v,reg_name,-1);
- sq_get(v,-2);
- sq_remove(v,-2);
- sq_createslot(v,-3);
-
- sq_settop(v,top);
- return SQ_OK;
- }
- sq_settop(v,top);
- return SQ_ERROR;
-}
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQSTD_STREAM_H_
-#define _SQSTD_STREAM_H_
-
-SQInteger _stream_readblob(HSQUIRRELVM v);
-SQInteger _stream_readline(HSQUIRRELVM v);
-SQInteger _stream_readn(HSQUIRRELVM v);
-SQInteger _stream_writeblob(HSQUIRRELVM v);
-SQInteger _stream_writen(HSQUIRRELVM v);
-SQInteger _stream_seek(HSQUIRRELVM v);
-SQInteger _stream_tell(HSQUIRRELVM v);
-SQInteger _stream_len(HSQUIRRELVM v);
-SQInteger _stream_eos(HSQUIRRELVM v);
-SQInteger _stream_flush(HSQUIRRELVM v);
-
-#define _DECL_STREAM_FUNC(name,nparams,typecheck) {_SC(#name),_stream_##name,nparams,typecheck}
-SQRESULT declare_stream(HSQUIRRELVM v,const SQChar* name,SQUserPointer typetag,const SQChar* reg_name,SQRegFunction *methods,SQRegFunction *globals);
-#endif /*_SQSTD_STREAM_H_*/
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#include <squirrel.h>
-#include <sqstdstring.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <assert.h>
-
-#ifdef SQUNICODE
-#define scstrchr wcschr
-#define scsnprintf wsnprintf
-#define scatoi _wtoi
-#define scstrtok wcstok
-#else
-#define scstrchr strchr
-#define scsnprintf snprintf
-#define scatoi atoi
-#define scstrtok strtok
-#endif
-#define MAX_FORMAT_LEN 20
-#define MAX_WFORMAT_LEN 3
-#define ADDITIONAL_FORMAT_SPACE (100*sizeof(SQChar))
-
-static SQInteger validate_format(HSQUIRRELVM v, SQChar *fmt, const SQChar *src, SQInteger n,SQInteger &width)
-{
- SQChar swidth[MAX_WFORMAT_LEN];
- SQInteger wc = 0;
- SQInteger start = n;
- fmt[0] = '%';
- while (scstrchr(_SC("-+ #0"), src[n])) n++;
- while (scisdigit(src[n])) {
- swidth[wc] = src[n];
- n++;
- wc++;
- if(wc>=MAX_WFORMAT_LEN)
- return sq_throwerror(v,_SC("width format too long"));
- }
- swidth[wc] = '\0';
- if(wc > 0) {
- width = scatoi(swidth);
- }
- else
- width = 0;
- if (src[n] == '.') {
- n++;
-
- wc = 0;
- while (scisdigit(src[n])) {
- swidth[wc] = src[n];
- n++;
- wc++;
- if(wc>=MAX_WFORMAT_LEN)
- return sq_throwerror(v,_SC("precision format too long"));
- }
- swidth[wc] = '\0';
- if(wc > 0) {
- width += scatoi(swidth);
- }
- }
- if (n-start > MAX_FORMAT_LEN )
- return sq_throwerror(v,_SC("format too long"));
- memcpy(&fmt[1],&src[start],((n-start)+1)*sizeof(SQChar));
- fmt[(n-start)+2] = '\0';
- return n;
-}
-
-
-SQRESULT sqstd_format(HSQUIRRELVM v,SQInteger nformatstringidx,SQInteger *outlen,SQChar **output)
-{
- const SQChar *format;
- SQChar *dest;
- SQChar fmt[MAX_FORMAT_LEN];
- sq_getstring(v,nformatstringidx,&format);
- SQInteger allocated = (sq_getsize(v,nformatstringidx)+2)*sizeof(SQChar);
- dest = sq_getscratchpad(v,allocated);
- SQInteger n = 0,i = 0, nparam = nformatstringidx+1, w = 0;
- while(format[n] != '\0') {
- if(format[n] != '%') {
- assert(i < allocated);
- dest[i++] = format[n];
- n++;
- }
- else if(format[n+1] == '%') { //handles %%
- dest[i++] = '%';
- n += 2;
- }
- else {
- n++;
- if( nparam > sq_gettop(v) )
- return sq_throwerror(v,_SC("not enough paramters for the given format string"));
- n = validate_format(v,fmt,format,n,w);
- if(n < 0) return -1;
- SQInteger addlen = 0;
- SQInteger valtype = 0;
- const SQChar *ts;
- SQInteger ti;
- SQFloat tf;
- switch(format[n]) {
- case 's':
- if(SQ_FAILED(sq_getstring(v,nparam,&ts)))
- return sq_throwerror(v,_SC("string expected for the specified format"));
- addlen = (sq_getsize(v,nparam)*sizeof(SQChar))+((w+1)*sizeof(SQChar));
- valtype = 's';
- break;
- case 'i': case 'd': case 'c':case 'o': case 'u': case 'x': case 'X':
- if(SQ_FAILED(sq_getinteger(v,nparam,&ti)))
- return sq_throwerror(v,_SC("integer expected for the specified format"));
- addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar));
- valtype = 'i';
- break;
- case 'f': case 'g': case 'G': case 'e': case 'E':
- if(SQ_FAILED(sq_getfloat(v,nparam,&tf)))
- return sq_throwerror(v,_SC("float expected for the specified format"));
- addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar));
- valtype = 'f';
- break;
- default:
- return sq_throwerror(v,_SC("invalid format"));
- }
- n++;
- allocated += addlen + sizeof(SQChar);
- dest = sq_getscratchpad(v,allocated);
- switch(valtype) {
- case 's': i += scsprintf(&dest[i],fmt,ts); break;
- case 'i': i += scsprintf(&dest[i],fmt,ti); break;
- case 'f': i += scsprintf(&dest[i],fmt,tf); break;
- };
- nparam ++;
- }
- }
- *outlen = i;
- dest[i] = '\0';
- *output = dest;
- return SQ_OK;
-}
-
-static SQInteger _string_format(HSQUIRRELVM v)
-{
- SQChar *dest = NULL;
- SQInteger length = 0;
- if(SQ_FAILED(sqstd_format(v,2,&length,&dest)))
- return -1;
- sq_pushstring(v,dest,length);
- return 1;
-}
-
-static void __strip_l(const SQChar *str,const SQChar **start)
-{
- const SQChar *t = str;
- while(((*t) != '\0') && scisspace(*t)){ t++; }
- *start = t;
-}
-
-static void __strip_r(const SQChar *str,SQInteger len,const SQChar **end)
-{
- if(len == 0) {
- *end = str;
- return;
- }
- const SQChar *t = &str[len-1];
- while(t != str && scisspace(*t)) { t--; }
- *end = t+1;
-}
-
-static SQInteger _string_strip(HSQUIRRELVM v)
-{
- const SQChar *str,*start,*end;
- sq_getstring(v,2,&str);
- SQInteger len = sq_getsize(v,2);
- __strip_l(str,&start);
- __strip_r(str,len,&end);
- sq_pushstring(v,start,end - start);
- return 1;
-}
-
-static SQInteger _string_lstrip(HSQUIRRELVM v)
-{
- const SQChar *str,*start;
- sq_getstring(v,2,&str);
- __strip_l(str,&start);
- sq_pushstring(v,start,-1);
- return 1;
-}
-
-static SQInteger _string_rstrip(HSQUIRRELVM v)
-{
- const SQChar *str,*end;
- sq_getstring(v,2,&str);
- SQInteger len = sq_getsize(v,2);
- __strip_r(str,len,&end);
- sq_pushstring(v,str,end - str);
- return 1;
-}
-
-static SQInteger _string_split(HSQUIRRELVM v)
-{
- const SQChar *str,*seps;
- SQChar *stemp,*tok;
- sq_getstring(v,2,&str);
- sq_getstring(v,3,&seps);
- if(sq_getsize(v,3) == 0) return sq_throwerror(v,_SC("empty separators string"));
- SQInteger memsize = (sq_getsize(v,2)+1)*sizeof(SQChar);
- stemp = sq_getscratchpad(v,memsize);
- memcpy(stemp,str,memsize);
- tok = scstrtok(stemp,seps);
- sq_newarray(v,0);
- while( tok != NULL ) {
- sq_pushstring(v,tok,-1);
- sq_arrayappend(v,-2);
- tok = scstrtok( NULL, seps );
- }
- return 1;
-}
-
-#define SETUP_REX(v) \
- SQRex *self = NULL; \
- sq_getinstanceup(v,1,(SQUserPointer *)&self,0);
-
-static SQInteger _rexobj_releasehook(SQUserPointer p, SQInteger size)
-{
- SQRex *self = ((SQRex *)p);
- sqstd_rex_free(self);
- return 1;
-}
-
-static SQInteger _regexp_match(HSQUIRRELVM v)
-{
- SETUP_REX(v);
- const SQChar *str;
- sq_getstring(v,2,&str);
- if(sqstd_rex_match(self,str) == SQTrue)
- {
- sq_pushbool(v,SQTrue);
- return 1;
- }
- sq_pushbool(v,SQFalse);
- return 1;
-}
-
-static void _addrexmatch(HSQUIRRELVM v,const SQChar *str,const SQChar *begin,const SQChar *end)
-{
- sq_newtable(v);
- sq_pushstring(v,_SC("begin"),-1);
- sq_pushinteger(v,begin - str);
- sq_rawset(v,-3);
- sq_pushstring(v,_SC("end"),-1);
- sq_pushinteger(v,end - str);
- sq_rawset(v,-3);
-}
-
-static SQInteger _regexp_search(HSQUIRRELVM v)
-{
- SETUP_REX(v);
- const SQChar *str,*begin,*end;
- SQInteger start = 0;
- sq_getstring(v,2,&str);
- if(sq_gettop(v) > 2) sq_getinteger(v,3,&start);
- if(sqstd_rex_search(self,str+start,&begin,&end) == SQTrue) {
- _addrexmatch(v,str,begin,end);
- return 1;
- }
- return 0;
-}
-
-static SQInteger _regexp_capture(HSQUIRRELVM v)
-{
- SETUP_REX(v);
- const SQChar *str,*begin,*end;
- SQInteger start = 0;
- sq_getstring(v,2,&str);
- if(sq_gettop(v) > 2) sq_getinteger(v,3,&start);
- if(sqstd_rex_search(self,str+start,&begin,&end) == SQTrue) {
- SQInteger n = sqstd_rex_getsubexpcount(self);
- SQRexMatch match;
- sq_newarray(v,0);
- for(SQInteger i = 0;i < n; i++) {
- sqstd_rex_getsubexp(self,i,&match);
- if(match.len > 0)
- _addrexmatch(v,str,match.begin,match.begin+match.len);
- else
- _addrexmatch(v,str,str,str); //empty match
- sq_arrayappend(v,-2);
- }
- return 1;
- }
- return 0;
-}
-
-static SQInteger _regexp_subexpcount(HSQUIRRELVM v)
-{
- SETUP_REX(v);
- sq_pushinteger(v,sqstd_rex_getsubexpcount(self));
- return 1;
-}
-
-static SQInteger _regexp_constructor(HSQUIRRELVM v)
-{
- const SQChar *error,*pattern;
- sq_getstring(v,2,&pattern);
- SQRex *rex = sqstd_rex_compile(pattern,&error);
- if(!rex) return sq_throwerror(v,error);
- sq_setinstanceup(v,1,rex);
- sq_setreleasehook(v,1,_rexobj_releasehook);
- return 0;
-}
-
-static SQInteger _regexp__typeof(HSQUIRRELVM v)
-{
- sq_pushstring(v,_SC("regexp"),-1);
- return 1;
-}
-
-#define _DECL_REX_FUNC(name,nparams,pmask) {_SC(#name),_regexp_##name,nparams,pmask}
-static SQRegFunction rexobj_funcs[]={
- _DECL_REX_FUNC(constructor,2,_SC(".s")),
- _DECL_REX_FUNC(search,-2,_SC("xsn")),
- _DECL_REX_FUNC(match,2,_SC("xs")),
- _DECL_REX_FUNC(capture,-2,_SC("xsn")),
- _DECL_REX_FUNC(subexpcount,1,_SC("x")),
- _DECL_REX_FUNC(_typeof,1,_SC("x")),
- {0,0}
-};
-
-#define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_string_##name,nparams,pmask}
-static SQRegFunction stringlib_funcs[]={
- _DECL_FUNC(format,-2,_SC(".s")),
- _DECL_FUNC(strip,2,_SC(".s")),
- _DECL_FUNC(lstrip,2,_SC(".s")),
- _DECL_FUNC(rstrip,2,_SC(".s")),
- _DECL_FUNC(split,3,_SC(".ss")),
- {0,0}
-};
-
-
-SQInteger sqstd_register_stringlib(HSQUIRRELVM v)
-{
- sq_pushstring(v,_SC("regexp"),-1);
- sq_newclass(v,SQFalse);
- SQInteger i = 0;
- while(rexobj_funcs[i].name != 0) {
- SQRegFunction &f = rexobj_funcs[i];
- sq_pushstring(v,f.name,-1);
- sq_newclosure(v,f.f,0);
- sq_setparamscheck(v,f.nparamscheck,f.typemask);
- sq_setnativeclosurename(v,-1,f.name);
- sq_createslot(v,-3);
- i++;
- }
- sq_createslot(v,-3);
-
- i = 0;
- while(stringlib_funcs[i].name!=0)
- {
- sq_pushstring(v,stringlib_funcs[i].name,-1);
- sq_newclosure(v,stringlib_funcs[i].f,0);
- sq_setparamscheck(v,stringlib_funcs[i].nparamscheck,stringlib_funcs[i].typemask);
- sq_setnativeclosurename(v,-1,stringlib_funcs[i].name);
- sq_createslot(v,-3);
- i++;
- }
- return 1;
-}
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#include <squirrel.h>
-#include <time.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sqstdsystem.h>
-
-#ifdef SQUNICODE
-#include <wchar.h>
-#define scgetenv _wgetenv
-#define scsystem _wsystem
-#define scasctime _wasctime
-#define scremove _wremove
-#define screname _wrename
-#else
-#define scgetenv getenv
-#define scsystem system
-#define scasctime asctime
-#define scremove remove
-#define screname rename
-#endif
-
-static SQInteger _system_getenv(HSQUIRRELVM v)
-{
- const SQChar *s;
- if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){
- sq_pushstring(v,scgetenv(s),-1);
- return 1;
- }
- return 0;
-}
-
-
-static SQInteger _system_system(HSQUIRRELVM v)
-{
- const SQChar *s;
- if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){
- sq_pushinteger(v,scsystem(s));
- return 1;
- }
- return sq_throwerror(v,_SC("wrong param"));
-}
-
-
-static SQInteger _system_clock(HSQUIRRELVM v)
-{
- sq_pushfloat(v,((SQFloat)clock())/(SQFloat)CLOCKS_PER_SEC);
- return 1;
-}
-
-static SQInteger _system_time(HSQUIRRELVM v)
-{
- time_t t;
- time(&t);
- sq_pushinteger(v,*((SQInteger *)&t));
- return 1;
-}
-
-static SQInteger _system_remove(HSQUIRRELVM v)
-{
- const SQChar *s;
- sq_getstring(v,2,&s);
- if(scremove(s)==-1)
- return sq_throwerror(v,_SC("remove() failed"));
- return 0;
-}
-
-static SQInteger _system_rename(HSQUIRRELVM v)
-{
- const SQChar *oldn,*newn;
- sq_getstring(v,2,&oldn);
- sq_getstring(v,3,&newn);
- if(screname(oldn,newn)==-1)
- return sq_throwerror(v,_SC("rename() failed"));
- return 0;
-}
-
-static void _set_integer_slot(HSQUIRRELVM v,const SQChar *name,SQInteger val)
-{
- sq_pushstring(v,name,-1);
- sq_pushinteger(v,val);
- sq_rawset(v,-3);
-}
-
-static SQInteger _system_date(HSQUIRRELVM v)
-{
- time_t t;
- SQInteger it;
- SQInteger format = 'l';
- if(sq_gettop(v) > 1) {
- sq_getinteger(v,2,&it);
- t = it;
- if(sq_gettop(v) > 2) {
- sq_getinteger(v,3,(SQInteger*)&format);
- }
- }
- else {
- time(&t);
- }
- tm *date;
- if(format == 'u')
- date = gmtime(&t);
- else
- date = localtime(&t);
- if(!date)
- return sq_throwerror(v,_SC("crt api failure"));
- sq_newtable(v);
- _set_integer_slot(v, _SC("sec"), date->tm_sec);
- _set_integer_slot(v, _SC("min"), date->tm_min);
- _set_integer_slot(v, _SC("hour"), date->tm_hour);
- _set_integer_slot(v, _SC("day"), date->tm_mday);
- _set_integer_slot(v, _SC("month"), date->tm_mon);
- _set_integer_slot(v, _SC("year"), date->tm_year+1900);
- _set_integer_slot(v, _SC("wday"), date->tm_wday);
- _set_integer_slot(v, _SC("yday"), date->tm_yday);
- return 1;
-}
-
-
-
-#define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_system_##name,nparams,pmask}
-static SQRegFunction systemlib_funcs[]={
- _DECL_FUNC(getenv,2,_SC(".s")),
- _DECL_FUNC(system,2,_SC(".s")),
- _DECL_FUNC(clock,1,NULL),
- _DECL_FUNC(time,1,NULL),
- _DECL_FUNC(date,-1,_SC(".nn")),
- _DECL_FUNC(remove,2,_SC(".s")),
- _DECL_FUNC(rename,3,_SC(".ss")),
- {0,0}
-};
-
-
-SQInteger sqstd_register_systemlib(HSQUIRRELVM v)
-{
- SQInteger i=0;
- while(systemlib_funcs[i].name!=0)
- {
- sq_pushstring(v,systemlib_funcs[i].name,-1);
- sq_newclosure(v,systemlib_funcs[i].f,0);
- sq_setparamscheck(v,systemlib_funcs[i].nparamscheck,systemlib_funcs[i].typemask);
- sq_setnativeclosurename(v,-1,systemlib_funcs[i].name);
- sq_createslot(v,-3);
- i++;
- }
- return 1;
-}
+++ /dev/null
-/*
- see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include "sqvm.h"
-#include "sqstring.h"
-#include "sqtable.h"
-#include "sqarray.h"
-#include "sqfuncproto.h"
-#include "sqclosure.h"
-#include "squserdata.h"
-#include "sqcompiler.h"
-#include "sqfuncstate.h"
-#include "sqclass.h"
-
-bool sq_aux_gettypedarg(HSQUIRRELVM v,SQInteger idx,SQObjectType type,SQObjectPtr **o)
-{
- *o = &stack_get(v,idx);
- if(type(**o) != type){
- SQObjectPtr oval = v->PrintObjVal(**o);
- v->Raise_Error(_SC("wrong argument type, expected '%s' got '%.50s'"),IdType2Name(type),_stringval(oval));
- return false;
- }
- return true;
-}
-
-#define _GETSAFE_OBJ(v,idx,type,o) { if(!sq_aux_gettypedarg(v,idx,type,&o)) return SQ_ERROR; }
-
-#define sq_aux_paramscheck(v,count) \
-{ \
- if(sq_gettop(v) < count){ v->Raise_Error(_SC("not enough params in the stack")); return SQ_ERROR; }\
-}
-
-SQInteger sq_aux_throwobject(HSQUIRRELVM v,SQObjectPtr &e)
-{
- v->_lasterror = e;
- return SQ_ERROR;
-}
-
-SQInteger sq_aux_invalidtype(HSQUIRRELVM v,SQObjectType type)
-{
- scsprintf(_ss(v)->GetScratchPad(100), _SC("unexpected type %s"), IdType2Name(type));
- return sq_throwerror(v, _ss(v)->GetScratchPad(-1));
-}
-
-HSQUIRRELVM sq_open(SQInteger initialstacksize)
-{
- SQSharedState *ss;
- SQVM *v;
- sq_new(ss, SQSharedState);
- ss->Init();
- v = (SQVM *)SQ_MALLOC(sizeof(SQVM));
- new (v) SQVM(ss);
- ss->_root_vm = v;
- if(v->Init(NULL, initialstacksize)) {
- return v;
- } else {
- sq_delete(v, SQVM);
- return NULL;
- }
- return v;
-}
-
-HSQUIRRELVM sq_newthread(HSQUIRRELVM friendvm, SQInteger initialstacksize)
-{
- SQSharedState *ss;
- SQVM *v;
- ss=_ss(friendvm);
-
- v= (SQVM *)SQ_MALLOC(sizeof(SQVM));
- new (v) SQVM(ss);
-
- if(v->Init(friendvm, initialstacksize)) {
- friendvm->Push(v);
- return v;
- } else {
- sq_delete(v, SQVM);
- return NULL;
- }
-}
-
-SQInteger sq_getvmstate(HSQUIRRELVM v)
-{
- if(v->_suspended)
- return SQ_VMSTATE_SUSPENDED;
- else {
- if(v->_callsstacksize != 0) return SQ_VMSTATE_RUNNING;
- else return SQ_VMSTATE_IDLE;
- }
-}
-
-void sq_seterrorhandler(HSQUIRRELVM v)
-{
- SQObject o = stack_get(v, -1);
- if(sq_isclosure(o) || sq_isnativeclosure(o) || sq_isnull(o)) {
- v->_errorhandler = o;
- v->Pop();
- }
-}
-
-void sq_setdebughook(HSQUIRRELVM v)
-{
- SQObject o = stack_get(v,-1);
- if(sq_isclosure(o) || sq_isnativeclosure(o) || sq_isnull(o)) {
- v->_debughook = o;
- v->Pop();
- }
-}
-
-void sq_close(HSQUIRRELVM v)
-{
- SQSharedState *ss = _ss(v);
- _thread(ss->_root_vm)->Finalize();
- sq_delete(ss, SQSharedState);
-}
-
-SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQChar *sourcename,SQBool raiseerror)
-{
- SQObjectPtr o;
- if(Compile(v, read, p, sourcename, o, raiseerror?true:false, _ss(v)->_debuginfo)) {
- v->Push(SQClosure::Create(_ss(v), _funcproto(o)));
- return SQ_OK;
- }
- return SQ_ERROR;
-}
-
-void sq_enabledebuginfo(HSQUIRRELVM v, SQBool enable)
-{
- _ss(v)->_debuginfo = enable?true:false;
-}
-
-void sq_notifyallexceptions(HSQUIRRELVM v, SQBool enable)
-{
- _ss(v)->_notifyallexceptions = enable?true:false;
-}
-
-void sq_addref(HSQUIRRELVM v,HSQOBJECT *po)
-{
- if(!ISREFCOUNTED(type(*po))) return;
-#ifdef NO_GARBAGE_COLLECTOR
- __AddRef(po->_type,po->_unVal);
-#else
- _ss(v)->_refs_table.AddRef(*po);
-#endif
-}
-
-SQBool sq_release(HSQUIRRELVM v,HSQOBJECT *po)
-{
- if(!ISREFCOUNTED(type(*po))) return SQTrue;
-#ifdef NO_GARBAGE_COLLECTOR
- __Release(po->_type,po->_unVal);
- return SQFalse; //the ret val doesn't work(and cannot be fixed)
-#else
- return _ss(v)->_refs_table.Release(*po);
-#endif
-}
-
-const SQChar *sq_objtostring(HSQOBJECT *o)
-{
- if(sq_type(*o) == OT_STRING) {
- return _stringval(*o);
- }
- return NULL;
-}
-
-SQInteger sq_objtointeger(HSQOBJECT *o)
-{
- if(sq_isnumeric(*o)) {
- return tointeger(*o);
- }
- return 0;
-}
-
-SQFloat sq_objtofloat(HSQOBJECT *o)
-{
- if(sq_isnumeric(*o)) {
- return tofloat(*o);
- }
- return 0;
-}
-
-SQBool sq_objtobool(HSQOBJECT *o)
-{
- if(sq_isbool(*o)) {
- return _integer(*o);
- }
- return SQFalse;
-}
-
-void sq_pushnull(HSQUIRRELVM v)
-{
- v->Push(_null_);
-}
-
-void sq_pushstring(HSQUIRRELVM v,const SQChar *s,SQInteger len)
-{
- if(s)
- v->Push(SQObjectPtr(SQString::Create(_ss(v), s, len)));
- else v->Push(_null_);
-}
-
-void sq_pushinteger(HSQUIRRELVM v,SQInteger n)
-{
- v->Push(n);
-}
-
-void sq_pushbool(HSQUIRRELVM v,SQBool b)
-{
- v->Push(b?true:false);
-}
-
-void sq_pushfloat(HSQUIRRELVM v,SQFloat n)
-{
- v->Push(n);
-}
-
-void sq_pushuserpointer(HSQUIRRELVM v,SQUserPointer p)
-{
- v->Push(p);
-}
-
-SQUserPointer sq_newuserdata(HSQUIRRELVM v,SQUnsignedInteger size)
-{
- SQUserData *ud = SQUserData::Create(_ss(v), size);
- v->Push(ud);
- return ud->_val;
-}
-
-void sq_newtable(HSQUIRRELVM v)
-{
- v->Push(SQTable::Create(_ss(v), 0));
-}
-
-void sq_newarray(HSQUIRRELVM v,SQInteger size)
-{
- v->Push(SQArray::Create(_ss(v), size));
-}
-
-SQRESULT sq_newclass(HSQUIRRELVM v,SQBool hasbase)
-{
- SQClass *baseclass = NULL;
- if(hasbase) {
- SQObjectPtr &base = stack_get(v,-1);
- if(type(base) != OT_CLASS)
- return sq_throwerror(v,_SC("invalid base type"));
- baseclass = _class(base);
- }
- SQClass *newclass = SQClass::Create(_ss(v), baseclass);
- if(baseclass) v->Pop();
- v->Push(newclass);
- return SQ_OK;
-}
-
-SQBool sq_instanceof(HSQUIRRELVM v)
-{
- SQObjectPtr &inst = stack_get(v,-1);
- SQObjectPtr &cl = stack_get(v,-2);
- if(type(inst) != OT_INSTANCE || type(cl) != OT_CLASS)
- return sq_throwerror(v,_SC("invalid param type"));
- return _instance(inst)->InstanceOf(_class(cl))?SQTrue:SQFalse;
-}
-
-SQRESULT sq_arrayappend(HSQUIRRELVM v,SQInteger idx)
-{
- sq_aux_paramscheck(v,2);
- SQObjectPtr *arr;
- _GETSAFE_OBJ(v, idx, OT_ARRAY,arr);
- _array(*arr)->Append(v->GetUp(-1));
- v->Pop(1);
- return SQ_OK;
-}
-
-SQRESULT sq_arraypop(HSQUIRRELVM v,SQInteger idx,SQBool pushval)
-{
- sq_aux_paramscheck(v, 1);
- SQObjectPtr *arr;
- _GETSAFE_OBJ(v, idx, OT_ARRAY,arr);
- if(_array(*arr)->Size() > 0) {
- if(pushval != 0){ v->Push(_array(*arr)->Top()); }
- _array(*arr)->Pop();
- return SQ_OK;
- }
- return sq_throwerror(v, _SC("empty array"));
-}
-
-SQRESULT sq_arrayresize(HSQUIRRELVM v,SQInteger idx,SQInteger newsize)
-{
- sq_aux_paramscheck(v,1);
- SQObjectPtr *arr;
- _GETSAFE_OBJ(v, idx, OT_ARRAY,arr);
- if(newsize >= 0) {
- _array(*arr)->Resize(newsize);
- return SQ_OK;
- }
- return sq_throwerror(v,_SC("negative size"));
-}
-
-
-SQRESULT sq_arrayreverse(HSQUIRRELVM v,SQInteger idx)
-{
- sq_aux_paramscheck(v, 1);
- SQObjectPtr *o;
- _GETSAFE_OBJ(v, idx, OT_ARRAY,o);
- SQArray *arr = _array(*o);
- if(arr->Size() > 0) {
- SQObjectPtr t;
- SQInteger size = arr->Size();
- SQInteger n = size >> 1; size -= 1;
- for(SQInteger i = 0; i < n; i++) {
- t = arr->_values[i];
- arr->_values[i] = arr->_values[size-i];
- arr->_values[size-i] = t;
- }
- return SQ_OK;
- }
- return SQ_OK;
-}
-
-SQRESULT sq_arrayremove(HSQUIRRELVM v,SQInteger idx,SQInteger itemidx)
-{
- sq_aux_paramscheck(v, 1);
- SQObjectPtr *arr;
- _GETSAFE_OBJ(v, idx, OT_ARRAY,arr);
- return _array(*arr)->Remove(itemidx) ? SQ_OK : sq_throwerror(v,_SC("index out of range"));
-}
-
-SQRESULT sq_arrayinsert(HSQUIRRELVM v,SQInteger idx,SQInteger destpos)
-{
- sq_aux_paramscheck(v, 1);
- SQObjectPtr *arr;
- _GETSAFE_OBJ(v, idx, OT_ARRAY,arr);
- SQRESULT ret = _array(*arr)->Insert(destpos, v->GetUp(-1)) ? SQ_OK : sq_throwerror(v,_SC("index out of range"));
- v->Pop();
- return ret;
-}
-
-
-void sq_newclosure(HSQUIRRELVM v,SQFUNCTION func,SQUnsignedInteger nfreevars)
-{
- SQNativeClosure *nc = SQNativeClosure::Create(_ss(v), func);
- nc->_nparamscheck = 0;
- for(SQUnsignedInteger i = 0; i < nfreevars; i++) {
- nc->_outervalues.push_back(v->Top());
- v->Pop();
- }
- v->Push(SQObjectPtr(nc));
-}
-
-SQRESULT sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger *nparams,SQUnsignedInteger *nfreevars)
-{
- SQObject o = stack_get(v, idx);
- if(sq_isclosure(o)) {
- SQClosure *c = _closure(o);
- SQFunctionProto *proto = _funcproto(c->_function);
- *nparams = (SQUnsignedInteger)proto->_nparameters;
- *nfreevars = (SQUnsignedInteger)c->_outervalues.size();
- return SQ_OK;
- }
- return sq_throwerror(v,_SC("the object is not a closure"));
-}
-
-SQRESULT sq_setnativeclosurename(HSQUIRRELVM v,SQInteger idx,const SQChar *name)
-{
- SQObject o = stack_get(v, idx);
- if(sq_isnativeclosure(o)) {
- SQNativeClosure *nc = _nativeclosure(o);
- nc->_name = SQString::Create(_ss(v),name);
- return SQ_OK;
- }
- return sq_throwerror(v,_SC("the object is not a nativeclosure"));
-}
-
-SQRESULT sq_setparamscheck(HSQUIRRELVM v,SQInteger nparamscheck,const SQChar *typemask)
-{
- SQObject o = stack_get(v, -1);
- if(!sq_isnativeclosure(o))
- return sq_throwerror(v, _SC("native closure expected"));
- SQNativeClosure *nc = _nativeclosure(o);
- nc->_nparamscheck = nparamscheck;
- if(typemask) {
- SQIntVec res;
- if(!CompileTypemask(res, typemask))
- return sq_throwerror(v, _SC("invalid typemask"));
- nc->_typecheck.copy(res);
- }
- else {
- nc->_typecheck.resize(0);
- }
- if(nparamscheck == SQ_MATCHTYPEMASKSTRING) {
- nc->_nparamscheck = nc->_typecheck.size();
- }
- return SQ_OK;
-}
-
-SQRESULT sq_bindenv(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr &o = stack_get(v,idx);
- if(!sq_isnativeclosure(o) &&
- !sq_isclosure(o))
- return sq_throwerror(v,_SC("the target is not a closure"));
- SQObjectPtr &env = stack_get(v,-1);
- if(!sq_istable(env) &&
- !sq_isclass(env) &&
- !sq_isinstance(env))
- return sq_throwerror(v,_SC("invalid environment"));
- SQObjectPtr w = _refcounted(env)->GetWeakRef(type(env));
- SQObjectPtr ret;
- if(sq_isclosure(o)) {
- SQClosure *c = _closure(o)->Clone();
- c->_env = w;
- ret = c;
- }
- else { //then must be a native closure
- SQNativeClosure *c = _nativeclosure(o)->Clone();
- c->_env = w;
- ret = c;
- }
- v->Pop();
- v->Push(ret);
- return SQ_OK;
-}
-
-SQRESULT sq_clear(HSQUIRRELVM v,SQInteger idx)
-{
- SQObject &o=stack_get(v,idx);
- switch(type(o)) {
- case OT_TABLE: _table(o)->Clear(); break;
- case OT_ARRAY: _array(o)->Resize(0); break;
- default:
- return sq_throwerror(v, _SC("clear only works on table and array"));
- break;
-
- }
- return SQ_OK;
-}
-
-void sq_pushroottable(HSQUIRRELVM v)
-{
- v->Push(v->_roottable);
-}
-
-void sq_pushregistrytable(HSQUIRRELVM v)
-{
- v->Push(_ss(v)->_registry);
-}
-
-void sq_pushconsttable(HSQUIRRELVM v)
-{
- v->Push(_ss(v)->_consts);
-}
-
-SQRESULT sq_setroottable(HSQUIRRELVM v)
-{
- SQObject o = stack_get(v, -1);
- if(sq_istable(o) || sq_isnull(o)) {
- v->_roottable = o;
- v->Pop();
- return SQ_OK;
- }
- return sq_throwerror(v, _SC("ivalid type"));
-}
-
-SQRESULT sq_setconsttable(HSQUIRRELVM v)
-{
- SQObject o = stack_get(v, -1);
- if(sq_istable(o)) {
- _ss(v)->_consts = o;
- v->Pop();
- return SQ_OK;
- }
- return sq_throwerror(v, _SC("ivalid type, expected table"));
-}
-
-void sq_setforeignptr(HSQUIRRELVM v,SQUserPointer p)
-{
- v->_foreignptr = p;
-}
-
-SQUserPointer sq_getforeignptr(HSQUIRRELVM v)
-{
- return v->_foreignptr;
-}
-
-void sq_push(HSQUIRRELVM v,SQInteger idx)
-{
- v->Push(stack_get(v, idx));
-}
-
-SQObjectType sq_gettype(HSQUIRRELVM v,SQInteger idx)
-{
- return type(stack_get(v, idx));
-}
-
-
-void sq_tostring(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr &o = stack_get(v, idx);
- SQObjectPtr res;
- v->ToString(o,res);
- v->Push(res);
-}
-
-void sq_tobool(HSQUIRRELVM v, SQInteger idx, SQBool *b)
-{
- SQObjectPtr &o = stack_get(v, idx);
- *b = v->IsFalse(o)?SQFalse:SQTrue;
-}
-
-SQRESULT sq_getinteger(HSQUIRRELVM v,SQInteger idx,SQInteger *i)
-{
- SQObjectPtr &o = stack_get(v, idx);
- if(sq_isnumeric(o)) {
- *i = tointeger(o);
- return SQ_OK;
- }
- return SQ_ERROR;
-}
-
-SQRESULT sq_getfloat(HSQUIRRELVM v,SQInteger idx,SQFloat *f)
-{
- SQObjectPtr &o = stack_get(v, idx);
- if(sq_isnumeric(o)) {
- *f = tofloat(o);
- return SQ_OK;
- }
- return SQ_ERROR;
-}
-
-SQRESULT sq_getbool(HSQUIRRELVM v,SQInteger idx,SQBool *b)
-{
- SQObjectPtr &o = stack_get(v, idx);
- if(sq_isbool(o)) {
- *b = _integer(o);
- return SQ_OK;
- }
- return SQ_ERROR;
-}
-
-SQRESULT sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar **c)
-{
- SQObjectPtr *o = NULL;
- _GETSAFE_OBJ(v, idx, OT_STRING,o);
- *c = _stringval(*o);
- return SQ_OK;
-}
-
-SQRESULT sq_getthread(HSQUIRRELVM v,SQInteger idx,HSQUIRRELVM *thread)
-{
- SQObjectPtr *o = NULL;
- _GETSAFE_OBJ(v, idx, OT_THREAD,o);
- *thread = _thread(*o);
- return SQ_OK;
-}
-
-SQRESULT sq_clone(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr &o = stack_get(v,idx);
- v->Push(_null_);
- if(!v->Clone(o, stack_get(v, -1))){
- v->Pop();
- return sq_aux_invalidtype(v, type(o));
- }
- return SQ_OK;
-}
-
-SQInteger sq_getsize(HSQUIRRELVM v, SQInteger idx)
-{
- SQObjectPtr &o = stack_get(v, idx);
- SQObjectType type = type(o);
- switch(type) {
- case OT_STRING: return _string(o)->_len;
- case OT_TABLE: return _table(o)->CountUsed();
- case OT_ARRAY: return _array(o)->Size();
- case OT_USERDATA: return _userdata(o)->_size;
- default:
- return sq_aux_invalidtype(v, type);
- }
-}
-
-SQRESULT sq_getuserdata(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p,SQUserPointer *typetag)
-{
- SQObjectPtr *o = NULL;
- _GETSAFE_OBJ(v, idx, OT_USERDATA,o);
- (*p) = _userdataval(*o);
- if(typetag) *typetag = _userdata(*o)->_typetag;
- return SQ_OK;
-}
-
-SQRESULT sq_settypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer typetag)
-{
- SQObjectPtr &o = stack_get(v,idx);
- switch(type(o)) {
- case OT_USERDATA: _userdata(o)->_typetag = typetag; break;
- case OT_CLASS: _class(o)->_typetag = typetag; break;
- default: return sq_throwerror(v,_SC("invalid object type"));
- }
- return SQ_OK;
-}
-
-SQRESULT sq_getobjtypetag(HSQOBJECT *o,SQUserPointer * typetag)
-{
- switch(type(*o)) {
- case OT_INSTANCE: *typetag = _instance(*o)->_class->_typetag; break;
- case OT_USERDATA: *typetag = _userdata(*o)->_typetag; break;
- case OT_CLASS: *typetag = _class(*o)->_typetag; break;
- default: return SQ_ERROR;
- }
- return SQ_OK;
-}
-
-SQRESULT sq_gettypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer *typetag)
-{
- SQObjectPtr &o = stack_get(v,idx);
- if(SQ_FAILED(sq_getobjtypetag(&o,typetag)))
- return sq_throwerror(v,_SC("invalid object type"));
- return SQ_OK;
-}
-
-SQRESULT sq_getuserpointer(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p)
-{
- SQObjectPtr *o = NULL;
- _GETSAFE_OBJ(v, idx, OT_USERPOINTER,o);
- (*p) = _userpointer(*o);
- return SQ_OK;
-}
-
-SQRESULT sq_setinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer p)
-{
- SQObjectPtr &o = stack_get(v,idx);
- if(type(o) != OT_INSTANCE) return sq_throwerror(v,_SC("the object is not a class instance"));
- _instance(o)->_userpointer = p;
- return SQ_OK;
-}
-
-SQRESULT sq_setclassudsize(HSQUIRRELVM v, SQInteger idx, SQInteger udsize)
-{
- SQObjectPtr &o = stack_get(v,idx);
- if(type(o) != OT_CLASS) return sq_throwerror(v,_SC("the object is not a class"));
- if(_class(o)->_locked) return sq_throwerror(v,_SC("the class is locked"));
- _class(o)->_udsize = udsize;
- return SQ_OK;
-}
-
-
-SQRESULT sq_getinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p,SQUserPointer typetag)
-{
- SQObjectPtr &o = stack_get(v,idx);
- if(type(o) != OT_INSTANCE) return sq_throwerror(v,_SC("the object is not a class instance"));
- (*p) = _instance(o)->_userpointer;
- if(typetag != 0) {
- SQClass *cl = _instance(o)->_class;
- do{
- if(cl->_typetag == typetag)
- return SQ_OK;
- cl = cl->_base;
- }while(cl != NULL);
- return sq_throwerror(v,_SC("invalid type tag"));
- }
- return SQ_OK;
-}
-
-SQInteger sq_gettop(HSQUIRRELVM v)
-{
- return (v->_top) - v->_stackbase;
-}
-
-void sq_settop(HSQUIRRELVM v, SQInteger newtop)
-{
- SQInteger top = sq_gettop(v);
- if(top > newtop)
- sq_pop(v, top - newtop);
- else
- while(top++ < newtop) sq_pushnull(v);
-}
-
-void sq_pop(HSQUIRRELVM v, SQInteger nelemstopop)
-{
- assert(v->_top >= nelemstopop);
- v->Pop(nelemstopop);
-}
-
-void sq_poptop(HSQUIRRELVM v)
-{
- assert(v->_top >= 1);
- v->Pop();
-}
-
-
-void sq_remove(HSQUIRRELVM v, SQInteger idx)
-{
- v->Remove(idx);
-}
-
-SQInteger sq_cmp(HSQUIRRELVM v)
-{
- SQInteger res;
- v->ObjCmp(stack_get(v, -1), stack_get(v, -2),res);
- return res;
-}
-
-SQRESULT sq_newslot(HSQUIRRELVM v, SQInteger idx, SQBool bstatic)
-{
- sq_aux_paramscheck(v, 3);
- SQObjectPtr &self = stack_get(v, idx);
- if(type(self) == OT_TABLE || type(self) == OT_CLASS) {
- SQObjectPtr &key = v->GetUp(-2);
- if(type(key) == OT_NULL) return sq_throwerror(v, _SC("null is not a valid key"));
- v->NewSlot(self, key, v->GetUp(-1),bstatic?true:false);
- v->Pop(2);
- }
- return SQ_OK;
-}
-
-SQRESULT sq_deleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval)
-{
- sq_aux_paramscheck(v, 2);
- SQObjectPtr *self;
- _GETSAFE_OBJ(v, idx, OT_TABLE,self);
- SQObjectPtr &key = v->GetUp(-1);
- if(type(key) == OT_NULL) return sq_throwerror(v, _SC("null is not a valid key"));
- SQObjectPtr res;
- if(!v->DeleteSlot(*self, key, res)){
- return SQ_ERROR;
- }
- if(pushval) v->GetUp(-1) = res;
- else v->Pop(1);
- return SQ_OK;
-}
-
-SQRESULT sq_set(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr &self = stack_get(v, idx);
- if(v->Set(self, v->GetUp(-2), v->GetUp(-1),false)) {
- v->Pop(2);
- return SQ_OK;
- }
- v->Raise_IdxError(v->GetUp(-2));return SQ_ERROR;
-}
-
-SQRESULT sq_rawset(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr &self = stack_get(v, idx);
- if(type(v->GetUp(-2)) == OT_NULL) return sq_throwerror(v, _SC("null key"));
- switch(type(self)) {
- case OT_TABLE:
- _table(self)->NewSlot(v->GetUp(-2), v->GetUp(-1));
- v->Pop(2);
- return SQ_OK;
- break;
- case OT_CLASS:
- _class(self)->NewSlot(_ss(v), v->GetUp(-2), v->GetUp(-1),false);
- v->Pop(2);
- return SQ_OK;
- break;
- case OT_INSTANCE:
- if(_instance(self)->Set(v->GetUp(-2), v->GetUp(-1))) {
- v->Pop(2);
- return SQ_OK;
- }
- break;
- case OT_ARRAY:
- if(v->Set(self, v->GetUp(-2), v->GetUp(-1),false)) {
- v->Pop(2);
- return SQ_OK;
- }
- break;
- default:
- v->Pop(2);
- return sq_throwerror(v, _SC("rawset works only on array/table/class and instance"));
- }
- v->Raise_IdxError(v->GetUp(-2));return SQ_ERROR;
-}
-
-SQRESULT sq_setdelegate(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr &self = stack_get(v, idx);
- SQObjectPtr &mt = v->GetUp(-1);
- SQObjectType type = type(self);
- switch(type) {
- case OT_TABLE:
- if(type(mt) == OT_TABLE) {
- if(!_table(self)->SetDelegate(_table(mt))) return sq_throwerror(v, _SC("delagate cycle")); v->Pop();}
- else if(type(mt)==OT_NULL) {
- _table(self)->SetDelegate(NULL); v->Pop(); }
- else return sq_aux_invalidtype(v,type);
- break;
- case OT_USERDATA:
- if(type(mt)==OT_TABLE) {
- _userdata(self)->SetDelegate(_table(mt)); v->Pop(); }
- else if(type(mt)==OT_NULL) {
- _userdata(self)->SetDelegate(NULL); v->Pop(); }
- else return sq_aux_invalidtype(v, type);
- break;
- default:
- return sq_aux_invalidtype(v, type);
- break;
- }
- return SQ_OK;
-}
-
-SQRESULT sq_rawdeleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval)
-{
- sq_aux_paramscheck(v, 2);
- SQObjectPtr *self;
- _GETSAFE_OBJ(v, idx, OT_TABLE,self);
- SQObjectPtr &key = v->GetUp(-1);
- SQObjectPtr t;
- if(_table(*self)->Get(key,t)) {
- _table(*self)->Remove(key);
- }
- if(pushval != 0)
- if(pushval) v->GetUp(-1) = t;
- else
- v->Pop(1);
- return SQ_OK;
-}
-
-SQRESULT sq_getdelegate(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr &self=stack_get(v,idx);
- switch(type(self)){
- case OT_TABLE:
- case OT_USERDATA:
- if(!_delegable(self)->_delegate){
- v->Push(_null_);
- break;
- }
- v->Push(SQObjectPtr(_delegable(self)->_delegate));
- break;
- default: return sq_throwerror(v,_SC("wrong type")); break;
- }
- return SQ_OK;
-
-}
-
-SQRESULT sq_get(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr &self=stack_get(v,idx);
- if(v->Get(self,v->GetUp(-1),v->GetUp(-1),false,false))
- return SQ_OK;
- v->Pop(1);
- return sq_throwerror(v,_SC("the index doesn't exist"));
-}
-
-SQRESULT sq_rawget(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr &self=stack_get(v,idx);
- switch(type(self)) {
- case OT_TABLE:
- if(_table(self)->Get(v->GetUp(-1),v->GetUp(-1)))
- return SQ_OK;
- break;
- case OT_CLASS:
- if(_class(self)->Get(v->GetUp(-1),v->GetUp(-1)))
- return SQ_OK;
- break;
- case OT_INSTANCE:
- if(_instance(self)->Get(v->GetUp(-1),v->GetUp(-1)))
- return SQ_OK;
- break;
- case OT_ARRAY:
- if(v->Get(self,v->GetUp(-1),v->GetUp(-1),false,false))
- return SQ_OK;
- break;
- default:
- v->Pop(1);
- return sq_throwerror(v,_SC("rawget works only on array/table/instance and class"));
- }
- v->Pop(1);
- return sq_throwerror(v,_SC("the index doesn't exist"));
-}
-
-SQRESULT sq_getstackobj(HSQUIRRELVM v,SQInteger idx,HSQOBJECT *po)
-{
- *po=stack_get(v,idx);
- return SQ_OK;
-}
-
-const SQChar *sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedInteger idx)
-{
- SQUnsignedInteger cstksize=v->_callsstacksize;
- SQUnsignedInteger lvl=(cstksize-level)-1;
- SQInteger stackbase=v->_stackbase;
- if(lvl<cstksize){
- for(SQUnsignedInteger i=0;i<level;i++){
- SQVM::CallInfo &ci=v->_callsstack[(cstksize-i)-1];
- stackbase-=ci._prevstkbase;
- }
- SQVM::CallInfo &ci=v->_callsstack[lvl];
- if(type(ci._closure)!=OT_CLOSURE)
- return NULL;
- SQClosure *c=_closure(ci._closure);
- SQFunctionProto *func=_funcproto(c->_function);
- if(func->_noutervalues > (SQInteger)idx) {
- v->Push(c->_outervalues[idx]);
- return _stringval(func->_outervalues[idx]._name);
- }
- idx -= func->_noutervalues;
- return func->GetLocal(v,stackbase,idx,(SQInteger)(ci._ip-func->_instructions)-1);
- }
- return NULL;
-}
-
-void sq_pushobject(HSQUIRRELVM v,HSQOBJECT obj)
-{
- v->Push(SQObjectPtr(obj));
-}
-
-void sq_resetobject(HSQOBJECT *po)
-{
- po->_unVal.pUserPointer=NULL;po->_type=OT_NULL;
-}
-
-SQRESULT sq_throwerror(HSQUIRRELVM v,const SQChar *err)
-{
- v->_lasterror=SQString::Create(_ss(v),err);
- return -1;
-}
-
-void sq_reseterror(HSQUIRRELVM v)
-{
- v->_lasterror = _null_;
-}
-
-void sq_getlasterror(HSQUIRRELVM v)
-{
- v->Push(v->_lasterror);
-}
-
-void sq_reservestack(HSQUIRRELVM v,SQInteger nsize)
-{
- if (((SQUnsignedInteger)v->_top + nsize) > v->_stack.size()) {
- v->_stack.resize(v->_stack.size() + ((v->_top + nsize) - v->_stack.size()));
- }
-}
-
-SQRESULT sq_resume(HSQUIRRELVM v,SQBool retval,SQBool raiseerror)
-{
- if(type(v->GetUp(-1))==OT_GENERATOR){
- v->Push(_null_); //retval
- if(!v->Execute(v->GetUp(-2),v->_top,0,v->_top,v->GetUp(-1),raiseerror,SQVM::ET_RESUME_GENERATOR))
- {v->Raise_Error(v->_lasterror); return SQ_ERROR;}
- if(!retval)
- v->Pop();
- return SQ_OK;
- }
- return sq_throwerror(v,_SC("only generators can be resumed"));
-}
-
-SQRESULT sq_call(HSQUIRRELVM v,SQInteger params,SQBool retval,SQBool raiseerror)
-{
- SQObjectPtr res;
- if(v->Call(v->GetUp(-(params+1)),params,v->_top-params,res,raiseerror?true:false)){
- if(!v->_suspended) {
- v->Pop(params);//pop closure and args
- }
- if(retval){
- v->Push(res); return SQ_OK;
- }
- return SQ_OK;
- }
- else {
- v->Pop(params);
- return SQ_ERROR;
- }
- if(!v->_suspended)
- v->Pop(params);
- return sq_throwerror(v,_SC("call failed"));
-}
-
-SQRESULT sq_suspendvm(HSQUIRRELVM v)
-{
- return v->Suspend();
-}
-
-SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool wakeupret,SQBool retval,SQBool raiseerror,SQBool throwerror)
-{
- SQObjectPtr ret;
- if(!v->_suspended)
- return sq_throwerror(v,_SC("cannot resume a vm that is not running any code"));
- if(wakeupret) {
- v->GetAt(v->_stackbase+v->_suspended_target)=v->GetUp(-1); //retval
- v->Pop();
- } else v->GetAt(v->_stackbase+v->_suspended_target)=_null_;
- if(!v->Execute(_null_,v->_top,-1,-1,ret,raiseerror,throwerror?SQVM::ET_RESUME_THROW_VM : SQVM::ET_RESUME_VM))
- return SQ_ERROR;
- if(sq_getvmstate(v) == SQ_VMSTATE_IDLE) {
- while (v->_top > 1) v->_stack[--v->_top] = _null_;
- }
- if(retval)
- v->Push(ret);
- return SQ_OK;
-}
-
-void sq_setreleasehook(HSQUIRRELVM v,SQInteger idx,SQRELEASEHOOK hook)
-{
- if(sq_gettop(v) >= 1){
- SQObjectPtr &ud=stack_get(v,idx);
- switch( type(ud) ) {
- case OT_USERDATA: _userdata(ud)->_hook = hook; break;
- case OT_INSTANCE: _instance(ud)->_hook = hook; break;
- case OT_CLASS: _class(ud)->_hook = hook; break;
- default: break; //shutup compiler
- }
- }
-}
-
-void sq_setcompilererrorhandler(HSQUIRRELVM v,SQCOMPILERERROR f)
-{
- _ss(v)->_compilererrorhandler = f;
-}
-
-SQRESULT sq_writeclosure(HSQUIRRELVM v,SQWRITEFUNC w,SQUserPointer up)
-{
- SQObjectPtr *o = NULL;
- _GETSAFE_OBJ(v, -1, OT_CLOSURE,o);
- unsigned short tag = SQ_BYTECODE_STREAM_TAG;
- if(w(up,&tag,2) != 2)
- return sq_throwerror(v,_SC("io error"));
- if(!_closure(*o)->Save(v,up,w))
- return SQ_ERROR;
- return SQ_OK;
-}
-
-SQRESULT sq_readclosure(HSQUIRRELVM v,SQREADFUNC r,SQUserPointer up)
-{
- SQObjectPtr closure;
-
- unsigned short tag;
- if(r(up,&tag,2) != 2)
- return sq_throwerror(v,_SC("io error"));
- if(tag != SQ_BYTECODE_STREAM_TAG)
- return sq_throwerror(v,_SC("invalid stream"));
- if(!SQClosure::Load(v,up,r,closure))
- return SQ_ERROR;
- v->Push(closure);
- return SQ_OK;
-}
-
-SQChar *sq_getscratchpad(HSQUIRRELVM v,SQInteger minsize)
-{
- return _ss(v)->GetScratchPad(minsize);
-}
-
-SQInteger sq_collectgarbage(HSQUIRRELVM v)
-{
-#ifndef NO_GARBAGE_COLLECTOR
- return _ss(v)->CollectGarbage(v);
-#else
- return -1;
-#endif
-}
-
-const SQChar *sq_getfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval)
-{
- SQObjectPtr &self = stack_get(v,idx);
- const SQChar *name = NULL;
- if(type(self) == OT_CLOSURE) {
- if(_closure(self)->_outervalues.size()>nval) {
- v->Push(_closure(self)->_outervalues[nval]);
- SQFunctionProto *fp = _funcproto(_closure(self)->_function);
- SQOuterVar &ov = fp->_outervalues[nval];
- name = _stringval(ov._name);
- }
- }
- return name;
-}
-
-SQRESULT sq_setfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval)
-{
- SQObjectPtr &self=stack_get(v,idx);
- switch(type(self))
- {
- case OT_CLOSURE:
- if(_closure(self)->_outervalues.size()>nval){
- _closure(self)->_outervalues[nval]=stack_get(v,-1);
- }
- else return sq_throwerror(v,_SC("invalid free var index"));
- break;
- case OT_NATIVECLOSURE:
- if(_nativeclosure(self)->_outervalues.size()>nval){
- _nativeclosure(self)->_outervalues[nval]=stack_get(v,-1);
- }
- else return sq_throwerror(v,_SC("invalid free var index"));
- break;
- default:
- return sq_aux_invalidtype(v,type(self));
- }
- v->Pop(1);
- return SQ_OK;
-}
-
-SQRESULT sq_setattributes(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr *o = NULL;
- _GETSAFE_OBJ(v, idx, OT_CLASS,o);
- SQObjectPtr &key = stack_get(v,-2);
- SQObjectPtr &val = stack_get(v,-1);
- SQObjectPtr attrs;
- if(type(key) == OT_NULL) {
- attrs = _class(*o)->_attributes;
- _class(*o)->_attributes = val;
- v->Pop(2);
- v->Push(attrs);
- return SQ_OK;
- }else if(_class(*o)->GetAttributes(key,attrs)) {
- _class(*o)->SetAttributes(key,val);
- v->Pop(2);
- v->Push(attrs);
- return SQ_OK;
- }
- return sq_throwerror(v,_SC("wrong index"));
-}
-
-SQRESULT sq_getattributes(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr *o = NULL;
- _GETSAFE_OBJ(v, idx, OT_CLASS,o);
- SQObjectPtr &key = stack_get(v,-1);
- SQObjectPtr attrs;
- if(type(key) == OT_NULL) {
- attrs = _class(*o)->_attributes;
- v->Pop();
- v->Push(attrs);
- return SQ_OK;
- }
- else if(_class(*o)->GetAttributes(key,attrs)) {
- v->Pop();
- v->Push(attrs);
- return SQ_OK;
- }
- return sq_throwerror(v,_SC("wrong index"));
-}
-
-SQRESULT sq_getbase(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr *o = NULL;
- _GETSAFE_OBJ(v, idx, OT_CLASS,o);
- if(_class(*o)->_base)
- v->Push(SQObjectPtr(_class(*o)->_base));
- else
- v->Push(_null_);
- return SQ_OK;
-}
-
-SQRESULT sq_getclass(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr *o = NULL;
- _GETSAFE_OBJ(v, idx, OT_INSTANCE,o);
- v->Push(SQObjectPtr(_instance(*o)->_class));
- return SQ_OK;
-}
-
-SQRESULT sq_createinstance(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr *o = NULL;
- _GETSAFE_OBJ(v, idx, OT_CLASS,o);
- v->Push(_class(*o)->CreateInstance());
- return SQ_OK;
-}
-
-void sq_weakref(HSQUIRRELVM v,SQInteger idx)
-{
- SQObject &o=stack_get(v,idx);
- if(ISREFCOUNTED(type(o))) {
- v->Push(_refcounted(o)->GetWeakRef(type(o)));
- return;
- }
- v->Push(o);
-}
-
-SQRESULT sq_getweakrefval(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr &o = stack_get(v,idx);
- if(type(o) != OT_WEAKREF) {
- return sq_throwerror(v,_SC("the object must be a weakref"));
- }
- v->Push(_weakref(o)->_obj);
- return SQ_OK;
-}
-
-SQRESULT sq_getdefaultdelegate(HSQUIRRELVM v,SQObjectType t)
-{
- SQSharedState *ss = _ss(v);
- switch(t) {
- case OT_TABLE: v->Push(ss->_table_default_delegate); break;
- case OT_ARRAY: v->Push(ss->_array_default_delegate); break;
- case OT_STRING: v->Push(ss->_string_default_delegate); break;
- case OT_INTEGER: case OT_FLOAT: v->Push(ss->_number_default_delegate); break;
- case OT_GENERATOR: v->Push(ss->_generator_default_delegate); break;
- case OT_CLOSURE: case OT_NATIVECLOSURE: v->Push(ss->_closure_default_delegate); break;
- case OT_THREAD: v->Push(ss->_thread_default_delegate); break;
- case OT_CLASS: v->Push(ss->_class_default_delegate); break;
- case OT_INSTANCE: v->Push(ss->_instance_default_delegate); break;
- case OT_WEAKREF: v->Push(ss->_weakref_default_delegate); break;
- default: return sq_throwerror(v,_SC("the type doesn't have a default delegate"));
- }
- return SQ_OK;
-}
-
-SQRESULT sq_next(HSQUIRRELVM v,SQInteger idx)
-{
- SQObjectPtr o=stack_get(v,idx),&refpos = stack_get(v,-1),realkey,val;
- if(type(o) == OT_GENERATOR) {
- return sq_throwerror(v,_SC("cannot iterate a generator"));
- }
- int faketojump;
- if(!v->FOREACH_OP(o,realkey,val,refpos,0,666,faketojump))
- return SQ_ERROR;
- if(faketojump != 666) {
- v->Push(realkey);
- v->Push(val);
- return SQ_OK;
- }
- return SQ_ERROR;
-}
-
-struct BufState{
- const SQChar *buf;
- SQInteger ptr;
- SQInteger size;
-};
-
-SQInteger buf_lexfeed(SQUserPointer file)
-{
- BufState *buf=(BufState*)file;
- if(buf->size<(buf->ptr+1))
- return 0;
- return buf->buf[buf->ptr++];
-}
-
-SQRESULT sq_compilebuffer(HSQUIRRELVM v,const SQChar *s,SQInteger size,const SQChar *sourcename,SQBool raiseerror) {
- BufState buf;
- buf.buf = s;
- buf.size = size;
- buf.ptr = 0;
- return sq_compile(v, buf_lexfeed, &buf, sourcename, raiseerror);
-}
-
-void sq_move(HSQUIRRELVM dest,HSQUIRRELVM src,SQInteger idx)
-{
- dest->Push(stack_get(src,idx));
-}
-
-void sq_setprintfunc(HSQUIRRELVM v, SQPRINTFUNCTION printfunc)
-{
- _ss(v)->_printfunc = printfunc;
-}
-
-SQPRINTFUNCTION sq_getprintfunc(HSQUIRRELVM v)
-{
- return _ss(v)->_printfunc;
-}
-
-void *sq_malloc(SQUnsignedInteger size)
-{
- return SQ_MALLOC(size);
-}
-
-void *sq_realloc(void* p,SQUnsignedInteger oldsize,SQUnsignedInteger newsize)
-{
- return SQ_REALLOC(p,oldsize,newsize);
-}
-
-void sq_free(void *p,SQUnsignedInteger size)
-{
- SQ_FREE(p,size);
-}
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQARRAY_H_
-#define _SQARRAY_H_
-
-struct SQArray : public CHAINABLE_OBJ
-{
-private:
- SQArray(SQSharedState *ss,SQInteger nsize){_values.resize(nsize); INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);}
- ~SQArray()
- {
- REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
- }
-public:
- static SQArray* Create(SQSharedState *ss,SQInteger nInitialSize){
- SQArray *newarray=(SQArray*)SQ_MALLOC(sizeof(SQArray));
- new (newarray) SQArray(ss,nInitialSize);
- return newarray;
- }
-#ifndef NO_GARBAGE_COLLECTOR
- void Mark(SQCollectable **chain);
-#endif
- void Finalize(){
- _values.resize(0);
- }
- bool Get(const SQInteger nidx,SQObjectPtr &val)
- {
- if(nidx>=0 && nidx<(SQInteger)_values.size()){
- SQObjectPtr &o = _values[nidx];
- val = _realval(o);
- return true;
- }
- else return false;
- }
- bool Set(const SQInteger nidx,const SQObjectPtr &val)
- {
- if(nidx>=0 && nidx<(SQInteger)_values.size()){
- _values[nidx]=val;
- return true;
- }
- else return false;
- }
- SQInteger Next(const SQObjectPtr &refpos,SQObjectPtr &outkey,SQObjectPtr &outval)
- {
- SQUnsignedInteger idx=TranslateIndex(refpos);
- while(idx<_values.size()){
- //first found
- outkey=(SQInteger)idx;
- SQObjectPtr &o = _values[idx];
- outval = _realval(o);
- //return idx for the next iteration
- return ++idx;
- }
- //nothing to iterate anymore
- return -1;
- }
- SQArray *Clone(){SQArray *anew=Create(_opt_ss(this),Size()); anew->_values.copy(_values); return anew; }
- SQInteger Size() const {return _values.size();}
- void Resize(SQInteger size,SQObjectPtr &fill = _null_) { _values.resize(size,fill); ShrinkIfNeeded(); }
- void Reserve(SQInteger size) { _values.reserve(size); }
- void Append(const SQObject &o){_values.push_back(o);}
- void Extend(const SQArray *a);
- SQObjectPtr &Top(){return _values.top();}
- void Pop(){_values.pop_back(); ShrinkIfNeeded(); }
- bool Insert(SQInteger idx,const SQObject &val){
- if(idx < 0 || idx > (SQInteger)_values.size())
- return false;
- _values.insert(idx,val);
- return true;
- }
- void ShrinkIfNeeded() {
- if(_values.size() <= _values.capacity()>>2) //shrink the array
- _values.shrinktofit();
- }
- bool Remove(SQInteger idx){
- if(idx < 0 || idx >= (SQInteger)_values.size())
- return false;
- _values.remove(idx);
- ShrinkIfNeeded();
- return true;
- }
- void Release()
- {
- sq_delete(this,SQArray);
- }
- SQObjectPtrVec _values;
-};
-#endif //_SQARRAY_H_
+++ /dev/null
-/*
- see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include "sqvm.h"
-#include "sqstring.h"
-#include "sqtable.h"
-#include "sqarray.h"
-#include "sqfuncproto.h"
-#include "sqclosure.h"
-#include "sqclass.h"
-#include <stdlib.h>
-#include <stdarg.h>
-#include <ctype.h>
-
-bool str2num(const SQChar *s,SQObjectPtr &res)
-{
- SQChar *end;
- if(scstrstr(s,_SC("."))){
- SQFloat r = SQFloat(scstrtod(s,&end));
- if(s == end) return false;
- res = r;
- return true;
- }
- else{
- SQInteger r = SQInteger(scstrtol(s,&end,10));
- if(s == end) return false;
- res = r;
- return true;
- }
-}
-
-static SQInteger base_dummy(HSQUIRRELVM v)
-{
- return 0;
-}
-
-#ifndef NO_GARBAGE_COLLECTOR
-static SQInteger base_collectgarbage(HSQUIRRELVM v)
-{
- sq_pushinteger(v, sq_collectgarbage(v));
- return 1;
-}
-#endif
-
-static SQInteger base_getroottable(HSQUIRRELVM v)
-{
- v->Push(v->_roottable);
- return 1;
-}
-
-static SQInteger base_getconsttable(HSQUIRRELVM v)
-{
- v->Push(_ss(v)->_consts);
- return 1;
-}
-
-
-static SQInteger base_setroottable(HSQUIRRELVM v)
-{
- SQObjectPtr &o=stack_get(v,2);
- if(SQ_FAILED(sq_setroottable(v))) return SQ_ERROR;
- v->Push(o);
- return 1;
-}
-
-static SQInteger base_setconsttable(HSQUIRRELVM v)
-{
- SQObjectPtr &o=stack_get(v,2);
- if(SQ_FAILED(sq_setconsttable(v))) return SQ_ERROR;
- v->Push(o);
- return 1;
-}
-
-static SQInteger base_seterrorhandler(HSQUIRRELVM v)
-{
- sq_seterrorhandler(v);
- return 0;
-}
-
-static SQInteger base_setdebughook(HSQUIRRELVM v)
-{
- sq_setdebughook(v);
- return 0;
-}
-
-static SQInteger base_enabledebuginfo(HSQUIRRELVM v)
-{
- SQObjectPtr &o=stack_get(v,2);
- sq_enabledebuginfo(v,(type(o) != OT_NULL)?1:0);
- return 0;
-}
-
-static SQInteger base_getstackinfos(HSQUIRRELVM v)
-{
- SQInteger level;
- SQStackInfos si;
- SQInteger seq = 0;
- const SQChar *name = NULL;
- sq_getinteger(v, -1, &level);
- if (SQ_SUCCEEDED(sq_stackinfos(v, level, &si)))
- {
- const SQChar *fn = _SC("unknown");
- const SQChar *src = _SC("unknown");
- if(si.funcname)fn = si.funcname;
- if(si.source)src = si.source;
- sq_newtable(v);
- sq_pushstring(v, _SC("func"), -1);
- sq_pushstring(v, fn, -1);
- sq_createslot(v, -3);
- sq_pushstring(v, _SC("src"), -1);
- sq_pushstring(v, src, -1);
- sq_createslot(v, -3);
- sq_pushstring(v, _SC("line"), -1);
- sq_pushinteger(v, si.line);
- sq_createslot(v, -3);
- sq_pushstring(v, _SC("locals"), -1);
- sq_newtable(v);
- seq=0;
- while ((name = sq_getlocal(v, level, seq))) {
- sq_pushstring(v, name, -1);
- sq_push(v, -2);
- sq_createslot(v, -4);
- sq_pop(v, 1);
- seq++;
- }
- sq_createslot(v, -3);
- return 1;
- }
-
- return 0;
-}
-
-static SQInteger base_assert(HSQUIRRELVM v)
-{
- if(v->IsFalse(stack_get(v,2))){
- return sq_throwerror(v,_SC("assertion failed"));
- }
- return 0;
-}
-
-static SQInteger get_slice_params(HSQUIRRELVM v,SQInteger &sidx,SQInteger &eidx,SQObjectPtr &o)
-{
- SQInteger top = sq_gettop(v);
- sidx=0;
- eidx=0;
- o=stack_get(v,1);
- SQObjectPtr &start=stack_get(v,2);
- if(type(start)!=OT_NULL && sq_isnumeric(start)){
- sidx=tointeger(start);
- }
- if(top>2){
- SQObjectPtr &end=stack_get(v,3);
- if(sq_isnumeric(end)){
- eidx=tointeger(end);
- }
- }
- else {
- eidx = sq_getsize(v,1);
- }
- return 1;
-}
-
-static SQInteger base_print(HSQUIRRELVM v)
-{
- const SQChar *str;
- sq_tostring(v,2);
- sq_getstring(v,-1,&str);
- if(_ss(v)->_printfunc) _ss(v)->_printfunc(v,_SC("%s"),str);
- return 0;
-}
-
-static SQInteger base_compilestring(HSQUIRRELVM v)
-{
- SQInteger nargs=sq_gettop(v);
- const SQChar *src=NULL,*name=_SC("unnamedbuffer");
- SQInteger size;
- sq_getstring(v,2,&src);
- size=sq_getsize(v,2);
- if(nargs>2){
- sq_getstring(v,3,&name);
- }
- if(SQ_SUCCEEDED(sq_compilebuffer(v,src,size,name,SQFalse)))
- return 1;
- else
- return SQ_ERROR;
-}
-
-static SQInteger base_newthread(HSQUIRRELVM v)
-{
- SQObjectPtr &func = stack_get(v,2);
- SQInteger stksize = (_funcproto(_closure(func)->_function)->_stacksize << 1) +2;
- HSQUIRRELVM newv = sq_newthread(v, (stksize < MIN_STACK_OVERHEAD + 2)? MIN_STACK_OVERHEAD + 2 : stksize);
- sq_move(newv,v,-2);
- return 1;
-}
-
-static SQInteger base_suspend(HSQUIRRELVM v)
-{
- return sq_suspendvm(v);
-}
-
-static SQInteger base_array(HSQUIRRELVM v)
-{
- SQArray *a;
- SQObject &size = stack_get(v,2);
- if(sq_gettop(v) > 2) {
- a = SQArray::Create(_ss(v),0);
- a->Resize(tointeger(size),stack_get(v,3));
- }
- else {
- a = SQArray::Create(_ss(v),tointeger(size));
- }
- v->Push(a);
- return 1;
-}
-
-static SQInteger base_type(HSQUIRRELVM v)
-{
- SQObjectPtr &o = stack_get(v,2);
- v->Push(SQString::Create(_ss(v),GetTypeName(o),-1));
- return 1;
-}
-
-static SQRegFunction base_funcs[]={
- //generic
- {_SC("seterrorhandler"),base_seterrorhandler,2, NULL},
- {_SC("setdebughook"),base_setdebughook,2, NULL},
- {_SC("enabledebuginfo"),base_enabledebuginfo,2, NULL},
- {_SC("getstackinfos"),base_getstackinfos,2, _SC(".n")},
- {_SC("getroottable"),base_getroottable,1, NULL},
- {_SC("setroottable"),base_setroottable,2, NULL},
- {_SC("getconsttable"),base_getconsttable,1, NULL},
- {_SC("setconsttable"),base_setconsttable,2, NULL},
- {_SC("assert"),base_assert,2, NULL},
- {_SC("print"),base_print,2, NULL},
- {_SC("compilestring"),base_compilestring,-2, _SC(".ss")},
- {_SC("newthread"),base_newthread,2, _SC(".c")},
- {_SC("suspend"),base_suspend,-1, NULL},
- {_SC("array"),base_array,-2, _SC(".n")},
- {_SC("type"),base_type,2, NULL},
- {_SC("dummy"),base_dummy,0,NULL},
-#ifndef NO_GARBAGE_COLLECTOR
- {_SC("collectgarbage"),base_collectgarbage,1, _SC("t")},
-#endif
- {0,0}
-};
-
-void sq_base_register(HSQUIRRELVM v)
-{
- SQInteger i=0;
- sq_pushroottable(v);
- while(base_funcs[i].name!=0) {
- sq_pushstring(v,base_funcs[i].name,-1);
- sq_newclosure(v,base_funcs[i].f,0);
- sq_setnativeclosurename(v,-1,base_funcs[i].name);
- sq_setparamscheck(v,base_funcs[i].nparamscheck,base_funcs[i].typemask);
- sq_createslot(v,-3);
- i++;
- }
- sq_pushstring(v,_SC("_version_"),-1);
- sq_pushstring(v,SQUIRREL_VERSION,-1);
- sq_createslot(v,-3);
- sq_pushstring(v,_SC("_charsize_"),-1);
- sq_pushinteger(v,sizeof(SQChar));
- sq_createslot(v,-3);
- sq_pushstring(v,_SC("_intsize_"),-1);
- sq_pushinteger(v,sizeof(SQInteger));
- sq_createslot(v,-3);
- sq_pushstring(v,_SC("_floatsize_"),-1);
- sq_pushinteger(v,sizeof(SQFloat));
- sq_createslot(v,-3);
- sq_pop(v,1);
-}
-
-static SQInteger default_delegate_len(HSQUIRRELVM v)
-{
- v->Push(SQInteger(sq_getsize(v,1)));
- return 1;
-}
-
-static SQInteger default_delegate_tofloat(HSQUIRRELVM v)
-{
- SQObjectPtr &o=stack_get(v,1);
- switch(type(o)){
- case OT_STRING:{
- SQObjectPtr res;
- if(str2num(_stringval(o),res)){
- v->Push(SQObjectPtr(tofloat(res)));
- break;
- }}
- return sq_throwerror(v, _SC("cannot convert the string"));
- break;
- case OT_INTEGER:case OT_FLOAT:
- v->Push(SQObjectPtr(tofloat(o)));
- break;
- case OT_BOOL:
- v->Push(SQObjectPtr((SQFloat)(_integer(o)?1:0)));
- break;
- default:
- v->Push(_null_);
- break;
- }
- return 1;
-}
-
-static SQInteger default_delegate_tointeger(HSQUIRRELVM v)
-{
- SQObjectPtr &o=stack_get(v,1);
- switch(type(o)){
- case OT_STRING:{
- SQObjectPtr res;
- if(str2num(_stringval(o),res)){
- v->Push(SQObjectPtr(tointeger(res)));
- break;
- }}
- return sq_throwerror(v, _SC("cannot convert the string"));
- break;
- case OT_INTEGER:case OT_FLOAT:
- v->Push(SQObjectPtr(tointeger(o)));
- break;
- case OT_BOOL:
- v->Push(SQObjectPtr(_integer(o)?(SQInteger)1:(SQInteger)0));
- break;
- default:
- v->Push(_null_);
- break;
- }
- return 1;
-}
-
-static SQInteger default_delegate_tostring(HSQUIRRELVM v)
-{
- sq_tostring(v,1);
- return 1;
-}
-
-static SQInteger obj_delegate_weakref(HSQUIRRELVM v)
-{
- sq_weakref(v,1);
- return 1;
-}
-
-static SQInteger obj_clear(HSQUIRRELVM v)
-{
- return sq_clear(v,-1);
-}
-
-
-static SQInteger number_delegate_tochar(HSQUIRRELVM v)
-{
- SQObject &o=stack_get(v,1);
- SQChar c = (SQChar)tointeger(o);
- v->Push(SQString::Create(_ss(v),(const SQChar *)&c,1));
- return 1;
-}
-
-
-/////////////////////////////////////////////////////////////////
-//TABLE DEFAULT DELEGATE
-
-static SQInteger table_rawdelete(HSQUIRRELVM v)
-{
- if(SQ_FAILED(sq_rawdeleteslot(v,1,SQTrue)))
- return SQ_ERROR;
- return 1;
-}
-
-
-static SQInteger container_rawexists(HSQUIRRELVM v)
-{
- if(SQ_SUCCEEDED(sq_rawget(v,-2))) {
- sq_pushbool(v,SQTrue);
- return 1;
- }
- sq_pushbool(v,SQFalse);
- return 1;
-}
-
-static SQInteger table_rawset(HSQUIRRELVM v)
-{
- return sq_rawset(v,-3);
-}
-
-
-static SQInteger table_rawget(HSQUIRRELVM v)
-{
- return SQ_SUCCEEDED(sq_rawget(v,-2))?1:SQ_ERROR;
-}
-
-
-SQRegFunction SQSharedState::_table_default_delegate_funcz[]={
- {_SC("len"),default_delegate_len,1, _SC("t")},
- {_SC("rawget"),table_rawget,2, _SC("t")},
- {_SC("rawset"),table_rawset,3, _SC("t")},
- {_SC("rawdelete"),table_rawdelete,2, _SC("t")},
- {_SC("rawin"),container_rawexists,2, _SC("t")},
- {_SC("weakref"),obj_delegate_weakref,1, NULL },
- {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
- {_SC("clear"),obj_clear,1, _SC(".")},
- {0,0}
-};
-
-//ARRAY DEFAULT DELEGATE///////////////////////////////////////
-
-static SQInteger array_append(HSQUIRRELVM v)
-{
- return sq_arrayappend(v,-2);
-}
-
-static SQInteger array_extend(HSQUIRRELVM v)
-{
- _array(stack_get(v,1))->Extend(_array(stack_get(v,2)));
- return 0;
-}
-
-static SQInteger array_reverse(HSQUIRRELVM v)
-{
- return sq_arrayreverse(v,-1);
-}
-
-static SQInteger array_pop(HSQUIRRELVM v)
-{
- return SQ_SUCCEEDED(sq_arraypop(v,1,SQTrue))?1:SQ_ERROR;
-}
-
-static SQInteger array_top(HSQUIRRELVM v)
-{
- SQObject &o=stack_get(v,1);
- if(_array(o)->Size()>0){
- v->Push(_array(o)->Top());
- return 1;
- }
- else return sq_throwerror(v,_SC("top() on a empty array"));
-}
-
-static SQInteger array_insert(HSQUIRRELVM v)
-{
- SQObject &o=stack_get(v,1);
- SQObject &idx=stack_get(v,2);
- SQObject &val=stack_get(v,3);
- if(!_array(o)->Insert(tointeger(idx),val))
- return sq_throwerror(v,_SC("index out of range"));
- return 0;
-}
-
-static SQInteger array_remove(HSQUIRRELVM v)
-{
- SQObject &o = stack_get(v, 1);
- SQObject &idx = stack_get(v, 2);
- if(!sq_isnumeric(idx)) return sq_throwerror(v, _SC("wrong type"));
- SQObjectPtr val;
- if(_array(o)->Get(tointeger(idx), val)) {
- _array(o)->Remove(tointeger(idx));
- v->Push(val);
- return 1;
- }
- return sq_throwerror(v, _SC("idx out of range"));
-}
-
-static SQInteger array_resize(HSQUIRRELVM v)
-{
- SQObject &o = stack_get(v, 1);
- SQObject &nsize = stack_get(v, 2);
- SQObjectPtr fill;
- if(sq_isnumeric(nsize)) {
- if(sq_gettop(v) > 2)
- fill = stack_get(v, 3);
- _array(o)->Resize(tointeger(nsize),fill);
- return 0;
- }
- return sq_throwerror(v, _SC("size must be a number"));
-}
-
-
-//QSORT ala Sedgewick
-bool _qsort_compare(HSQUIRRELVM v,SQObjectPtr &arr,SQObjectPtr &a,SQObjectPtr &b,SQInteger func,SQInteger &ret)
-{
- if(func < 0) {
- if(!v->ObjCmp(a,b,ret)) return false;
- }
- else {
- SQInteger top = sq_gettop(v);
- sq_push(v, func);
- sq_pushroottable(v);
- v->Push(a);
- v->Push(b);
- if(SQ_FAILED(sq_call(v, 3, SQTrue, SQFalse))) {
- if(!sq_isstring( v->_lasterror))
- v->Raise_Error(_SC("compare func failed"));
- return false;
- }
- sq_getinteger(v, -1, &ret);
- sq_settop(v, top);
- return true;
- }
- return true;
-}
-//QSORT ala Sedgewick
-bool _qsort(HSQUIRRELVM v,SQObjectPtr &arr, SQInteger l, SQInteger r,SQInteger func)
-{
- SQInteger i, j;
- SQArray *a=_array(arr);
- SQObjectPtr pivot,t;
- if( l < r ){
- pivot = a->_values[l];
- i = l; j = r+1;
- while(1){
- SQInteger ret;
- do {
- ++i;
- if(i > r) break;
- if(!_qsort_compare(v,arr,a->_values[i],pivot,func,ret))
- return false;
- } while( ret <= 0);
- do {
- --j;
- if ( j < 0 ) {
- v->Raise_Error( _SC("Invalid qsort, probably compare function defect") );
- return false;
- }
- if(!_qsort_compare(v,arr,a->_values[j],pivot,func,ret))
- return false;
- }
- while( ret > 0 );
- if( i >= j ) break;
- t = a->_values[i]; a->_values[i] = a->_values[j]; a->_values[j] = t;
- }
- t = a->_values[l]; a->_values[l] = a->_values[j]; a->_values[j] = t;
- if(!_qsort( v, arr, l, j-1,func)) return false;
- if(!_qsort( v, arr, j+1, r,func)) return false;
- }
- return true;
-}
-
-static SQInteger array_sort(HSQUIRRELVM v)
-{
- SQInteger func = -1;
- SQObjectPtr &o = stack_get(v,1);
- SQObject &funcobj = stack_get(v,2);
- if(_array(o)->Size() > 1) {
- if(type(funcobj) == OT_CLOSURE || type(funcobj) == OT_NATIVECLOSURE) func = 2;
- if(!_qsort(v, o, 0, _array(o)->Size()-1, func))
- return SQ_ERROR;
-
- }
- return 0;
-}
-static SQInteger array_slice(HSQUIRRELVM v)
-{
- SQInteger sidx,eidx;
- SQObjectPtr o;
- if(get_slice_params(v,sidx,eidx,o)==-1)return -1;
- SQInteger alen = _array(o)->Size();
- if(sidx < 0)sidx = alen + sidx;
- if(eidx < 0)eidx = alen + eidx;
- if(eidx < sidx)return sq_throwerror(v,_SC("wrong indexes"));
- if(eidx > alen)return sq_throwerror(v,_SC("slice out of range"));
- SQArray *arr=SQArray::Create(_ss(v),eidx-sidx);
- SQObjectPtr t;
- SQInteger count=0;
- for(SQInteger i=sidx;i<eidx;i++){
- _array(o)->Get(i,t);
- arr->Set(count++,t);
- }
- v->Push(arr);
- return 1;
-
-}
-
-SQRegFunction SQSharedState::_array_default_delegate_funcz[]={
- {_SC("len"),default_delegate_len,1, _SC("a")},
- {_SC("append"),array_append,2, _SC("a")},
- {_SC("extend"),array_extend,2, _SC("aa")},
- {_SC("push"),array_append,2, _SC("a")},
- {_SC("pop"),array_pop,1, _SC("a")},
- {_SC("top"),array_top,1, _SC("a")},
- {_SC("insert"),array_insert,3, _SC("an")},
- {_SC("remove"),array_remove,2, _SC("an")},
- {_SC("resize"),array_resize,-2, _SC("an")},
- {_SC("reverse"),array_reverse,1, _SC("a")},
- {_SC("sort"),array_sort,-1, _SC("ac")},
- {_SC("slice"),array_slice,-1, _SC("ann")},
- {_SC("weakref"),obj_delegate_weakref,1, NULL },
- {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
- {_SC("clear"),obj_clear,1, _SC(".")},
- {0,0}
-};
-
-//STRING DEFAULT DELEGATE//////////////////////////
-static SQInteger string_slice(HSQUIRRELVM v)
-{
- SQInteger sidx,eidx;
- SQObjectPtr o;
- if(SQ_FAILED(get_slice_params(v,sidx,eidx,o)))return -1;
- SQInteger slen = _string(o)->_len;
- if(sidx < 0)sidx = slen + sidx;
- if(eidx < 0)eidx = slen + eidx;
- if(eidx < sidx) return sq_throwerror(v,_SC("wrong indexes"));
- if(eidx > slen) return sq_throwerror(v,_SC("slice out of range"));
- v->Push(SQString::Create(_ss(v),&_stringval(o)[sidx],eidx-sidx));
- return 1;
-}
-
-static SQInteger string_find(HSQUIRRELVM v)
-{
- SQInteger top,start_idx=0;
- const SQChar *str,*substr,*ret;
- if(((top=sq_gettop(v))>1) && SQ_SUCCEEDED(sq_getstring(v,1,&str)) && SQ_SUCCEEDED(sq_getstring(v,2,&substr))){
- if(top>2)sq_getinteger(v,3,&start_idx);
- if((sq_getsize(v,1)>start_idx) && (start_idx>=0)){
- ret=scstrstr(&str[start_idx],substr);
- if(ret){
- sq_pushinteger(v,(SQInteger)(ret-str));
- return 1;
- }
- }
- return 0;
- }
- return sq_throwerror(v,_SC("invalid param"));
-}
-
-#define STRING_TOFUNCZ(func) static SQInteger string_##func(HSQUIRRELVM v) \
-{ \
- SQObject str=stack_get(v,1); \
- SQInteger len=_string(str)->_len; \
- const SQChar *sThis=_stringval(str); \
- SQChar *sNew=(_ss(v)->GetScratchPad(rsl(len))); \
- for(SQInteger i=0;i<len;i++) sNew[i]=func(sThis[i]); \
- v->Push(SQString::Create(_ss(v),sNew,len)); \
- return 1; \
-}
-
-
-STRING_TOFUNCZ(tolower)
-STRING_TOFUNCZ(toupper)
-
-SQRegFunction SQSharedState::_string_default_delegate_funcz[]={
- {_SC("len"),default_delegate_len,1, _SC("s")},
- {_SC("tointeger"),default_delegate_tointeger,1, _SC("s")},
- {_SC("tofloat"),default_delegate_tofloat,1, _SC("s")},
- {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
- {_SC("slice"),string_slice,-1, _SC(" s n n")},
- {_SC("find"),string_find,-2, _SC("s s n ")},
- {_SC("tolower"),string_tolower,1, _SC("s")},
- {_SC("toupper"),string_toupper,1, _SC("s")},
- {_SC("weakref"),obj_delegate_weakref,1, NULL },
- {0,0}
-};
-
-//INTEGER DEFAULT DELEGATE//////////////////////////
-SQRegFunction SQSharedState::_number_default_delegate_funcz[]={
- {_SC("tointeger"),default_delegate_tointeger,1, _SC("n|b")},
- {_SC("tofloat"),default_delegate_tofloat,1, _SC("n|b")},
- {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
- {_SC("tochar"),number_delegate_tochar,1, _SC("n|b")},
- {_SC("weakref"),obj_delegate_weakref,1, NULL },
- {0,0}
-};
-
-//CLOSURE DEFAULT DELEGATE//////////////////////////
-static SQInteger closure_pcall(HSQUIRRELVM v)
-{
- return SQ_SUCCEEDED(sq_call(v,sq_gettop(v)-1,SQTrue,SQFalse))?1:SQ_ERROR;
-}
-
-static SQInteger closure_call(HSQUIRRELVM v)
-{
- return SQ_SUCCEEDED(sq_call(v,sq_gettop(v)-1,SQTrue,SQTrue))?1:SQ_ERROR;
-}
-
-static SQInteger _closure_acall(HSQUIRRELVM v,SQBool raiseerror)
-{
- SQArray *aparams=_array(stack_get(v,2));
- SQInteger nparams=aparams->Size();
- v->Push(stack_get(v,1));
- for(SQInteger i=0;i<nparams;i++)v->Push(aparams->_values[i]);
- return SQ_SUCCEEDED(sq_call(v,nparams,SQTrue,raiseerror))?1:SQ_ERROR;
-}
-
-static SQInteger closure_acall(HSQUIRRELVM v)
-{
- return _closure_acall(v,SQTrue);
-}
-
-static SQInteger closure_pacall(HSQUIRRELVM v)
-{
- return _closure_acall(v,SQFalse);
-}
-
-static SQInteger closure_bindenv(HSQUIRRELVM v)
-{
- if(SQ_FAILED(sq_bindenv(v,1)))
- return SQ_ERROR;
- return 1;
-}
-
-static SQInteger closure_getinfos(HSQUIRRELVM v) {
- SQObject o = stack_get(v,1);
- SQTable *res = SQTable::Create(_ss(v),4);
- if(type(o) == OT_CLOSURE) {
- SQFunctionProto *f = _funcproto(_closure(o)->_function);
- SQInteger nparams = f->_nparameters + (f->_varparams?1:0);
- SQObjectPtr params = SQArray::Create(_ss(v),nparams);
- for(SQInteger n = 0; n<f->_nparameters; n++) {
- _array(params)->Set((SQInteger)n,f->_parameters[n]);
- }
- if(f->_varparams) {
- _array(params)->Set(nparams-1,SQString::Create(_ss(v),_SC("..."),-1));
- }
- res->NewSlot(SQString::Create(_ss(v),_SC("native"),-1),false);
- res->NewSlot(SQString::Create(_ss(v),_SC("name"),-1),f->_name);
- res->NewSlot(SQString::Create(_ss(v),_SC("src"),-1),f->_sourcename);
- res->NewSlot(SQString::Create(_ss(v),_SC("parameters"),-1),params);
- res->NewSlot(SQString::Create(_ss(v),_SC("varargs"),-1),f->_varparams);
- }
- else { //OT_NATIVECLOSURE
- SQNativeClosure *nc = _nativeclosure(o);
- res->NewSlot(SQString::Create(_ss(v),_SC("native"),-1),true);
- res->NewSlot(SQString::Create(_ss(v),_SC("name"),-1),nc->_name);
- res->NewSlot(SQString::Create(_ss(v),_SC("paramscheck"),-1),nc->_nparamscheck);
- SQObjectPtr typecheck;
- if(nc->_typecheck.size() > 0) {
- typecheck =
- SQArray::Create(_ss(v), nc->_typecheck.size());
- for(SQUnsignedInteger n = 0; n<nc->_typecheck.size(); n++) {
- _array(typecheck)->Set((SQInteger)n,nc->_typecheck[n]);
- }
- }
- res->NewSlot(SQString::Create(_ss(v),_SC("typecheck"),-1),typecheck);
- }
- v->Push(res);
- return 1;
-}
-
-
-SQRegFunction SQSharedState::_closure_default_delegate_funcz[]={
- {_SC("call"),closure_call,-1, _SC("c")},
- {_SC("pcall"),closure_pcall,-1, _SC("c")},
- {_SC("acall"),closure_acall,2, _SC("ca")},
- {_SC("pacall"),closure_pacall,2, _SC("ca")},
- {_SC("weakref"),obj_delegate_weakref,1, NULL },
- {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
- {_SC("bindenv"),closure_bindenv,2, _SC("c x|y|t")},
- {_SC("getinfos"),closure_getinfos,1, _SC("c")},
- {0,0}
-};
-
-//GENERATOR DEFAULT DELEGATE
-static SQInteger generator_getstatus(HSQUIRRELVM v)
-{
- SQObject &o=stack_get(v,1);
- switch(_generator(o)->_state){
- case SQGenerator::eSuspended:v->Push(SQString::Create(_ss(v),_SC("suspended")));break;
- case SQGenerator::eRunning:v->Push(SQString::Create(_ss(v),_SC("running")));break;
- case SQGenerator::eDead:v->Push(SQString::Create(_ss(v),_SC("dead")));break;
- }
- return 1;
-}
-
-SQRegFunction SQSharedState::_generator_default_delegate_funcz[]={
- {_SC("getstatus"),generator_getstatus,1, _SC("g")},
- {_SC("weakref"),obj_delegate_weakref,1, NULL },
- {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
- {0,0}
-};
-
-//THREAD DEFAULT DELEGATE
-
-static SQInteger thread_call(HSQUIRRELVM v)
-{
-
- SQObjectPtr o = stack_get(v,1);
- if(type(o) == OT_THREAD) {
- SQInteger nparams = sq_gettop(v);
- _thread(o)->Push(_thread(o)->_roottable);
- for(SQInteger i = 2; i<(nparams+1); i++)
- sq_move(_thread(o),v,i);
- if(SQ_SUCCEEDED(sq_call(_thread(o),nparams,SQTrue,SQFalse))) {
- sq_move(v,_thread(o),-1);
- sq_pop(_thread(o),1);
- return 1;
- }
- v->_lasterror = _thread(o)->_lasterror;
- return SQ_ERROR;
- }
- return sq_throwerror(v,_SC("wrong parameter"));
-}
-
-static SQInteger thread_wakeup(HSQUIRRELVM v)
-{
- SQObjectPtr o = stack_get(v,1);
- if(type(o) == OT_THREAD) {
- SQVM *thread = _thread(o);
- SQInteger state = sq_getvmstate(thread);
- if(state != SQ_VMSTATE_SUSPENDED) {
- switch(state) {
- case SQ_VMSTATE_IDLE:
- return sq_throwerror(v,_SC("cannot wakeup a idle thread"));
- break;
- case SQ_VMSTATE_RUNNING:
- return sq_throwerror(v,_SC("cannot wakeup a running thread"));
- break;
- }
- }
-
- SQInteger wakeupret = sq_gettop(v)>1?1:0;
- if(wakeupret) {
- sq_move(thread,v,2);
- }
- if(SQ_SUCCEEDED(sq_wakeupvm(thread,wakeupret,SQTrue,SQTrue,SQFalse))) {
- sq_move(v,thread,-1);
- sq_pop(thread,1); //pop retval
- if(sq_getvmstate(thread) == SQ_VMSTATE_IDLE) {
- sq_settop(thread,1); //pop roottable
- }
- return 1;
- }
- sq_settop(thread,1);
- v->_lasterror = thread->_lasterror;
- return SQ_ERROR;
- }
- return sq_throwerror(v,_SC("wrong parameter"));
-}
-
-static SQInteger thread_getstatus(HSQUIRRELVM v)
-{
- SQObjectPtr &o = stack_get(v,1);
- switch(sq_getvmstate(_thread(o))) {
- case SQ_VMSTATE_IDLE:
- sq_pushstring(v,_SC("idle"),-1);
- break;
- case SQ_VMSTATE_RUNNING:
- sq_pushstring(v,_SC("running"),-1);
- break;
- case SQ_VMSTATE_SUSPENDED:
- sq_pushstring(v,_SC("suspended"),-1);
- break;
- default:
- return sq_throwerror(v,_SC("internal VM error"));
- }
- return 1;
-}
-
-SQRegFunction SQSharedState::_thread_default_delegate_funcz[] = {
- {_SC("call"), thread_call, -1, _SC("v")},
- {_SC("wakeup"), thread_wakeup, -1, _SC("v")},
- {_SC("getstatus"), thread_getstatus, 1, _SC("v")},
- {_SC("weakref"),obj_delegate_weakref,1, NULL },
- {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
- {0,0},
-};
-
-static SQInteger class_getattributes(HSQUIRRELVM v)
-{
- if(SQ_SUCCEEDED(sq_getattributes(v,-2)))
- return 1;
- return SQ_ERROR;
-}
-
-static SQInteger class_setattributes(HSQUIRRELVM v)
-{
- if(SQ_SUCCEEDED(sq_setattributes(v,-3)))
- return 1;
- return SQ_ERROR;
-}
-
-static SQInteger class_instance(HSQUIRRELVM v)
-{
- if(SQ_SUCCEEDED(sq_createinstance(v,-1)))
- return 1;
- return SQ_ERROR;
-}
-
-SQRegFunction SQSharedState::_class_default_delegate_funcz[] = {
- {_SC("getattributes"), class_getattributes, 2, _SC("y.")},
- {_SC("setattributes"), class_setattributes, 3, _SC("y..")},
- {_SC("rawin"),container_rawexists,2, _SC("y")},
- {_SC("weakref"),obj_delegate_weakref,1, NULL },
- {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
- {_SC("instance"),class_instance,1, _SC("y")},
- {0,0}
-};
-
-static SQInteger instance_getclass(HSQUIRRELVM v)
-{
- if(SQ_SUCCEEDED(sq_getclass(v,1)))
- return 1;
- return SQ_ERROR;
-}
-
-SQRegFunction SQSharedState::_instance_default_delegate_funcz[] = {
- {_SC("getclass"), instance_getclass, 1, _SC("x")},
- {_SC("rawin"),container_rawexists,2, _SC("x")},
- {_SC("weakref"),obj_delegate_weakref,1, NULL },
- {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
- {0,0}
-};
-
-static SQInteger weakref_ref(HSQUIRRELVM v)
-{
- if(SQ_FAILED(sq_getweakrefval(v,1)))
- return SQ_ERROR;
- return 1;
-}
-
-SQRegFunction SQSharedState::_weakref_default_delegate_funcz[] = {
- {_SC("ref"),weakref_ref,1, _SC("r")},
- {_SC("weakref"),obj_delegate_weakref,1, NULL },
- {_SC("tostring"),default_delegate_tostring,1, _SC(".")},
- {0,0}
-};
-
-
+++ /dev/null
-/*
- see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include "sqvm.h"
-#include "sqtable.h"
-#include "sqclass.h"
-#include "sqclosure.h"
-
-SQClass::SQClass(SQSharedState *ss,SQClass *base)
-{
- _base = base;
- _typetag = 0;
- _hook = NULL;
- _udsize = 0;
- _metamethods.resize(MT_LAST); //size it to max size
- if(_base) {
- _defaultvalues.copy(base->_defaultvalues);
- _methods.copy(base->_methods);
- _metamethods.copy(base->_metamethods);
- __ObjAddRef(_base);
- }
- _members = base?base->_members->Clone() : SQTable::Create(ss,0);
- __ObjAddRef(_members);
- _locked = false;
- INIT_CHAIN();
- ADD_TO_CHAIN(&_sharedstate->_gc_chain, this);
-}
-
-void SQClass::Finalize() {
- _attributes = _null_;
- _defaultvalues.resize(0);
- _methods.resize(0);
- _metamethods.resize(0);
- __ObjRelease(_members);
- if(_base) {
- __ObjRelease(_base);
- }
-}
-
-SQClass::~SQClass()
-{
- REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
- Finalize();
-}
-
-bool SQClass::NewSlot(SQSharedState *ss,const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic)
-{
- SQObjectPtr temp;
- if(_locked)
- return false; //the class already has an instance so cannot be modified
- if(_members->Get(key,temp) && _isfield(temp)) //overrides the default value
- {
- _defaultvalues[_member_idx(temp)].val = val;
- return true;
- }
- if(type(val) == OT_CLOSURE || type(val) == OT_NATIVECLOSURE || bstatic) {
- SQInteger mmidx;
- if((type(val) == OT_CLOSURE || type(val) == OT_NATIVECLOSURE) &&
- (mmidx = ss->GetMetaMethodIdxByName(key)) != -1) {
- _metamethods[mmidx] = val;
- }
- else {
- if(type(temp) == OT_NULL) {
- SQClassMember m;
- m.val = val;
- _members->NewSlot(key,SQObjectPtr(_make_method_idx(_methods.size())));
- _methods.push_back(m);
- }
- else {
- _methods[_member_idx(temp)].val = val;
- }
- }
- return true;
- }
- SQClassMember m;
- m.val = val;
- _members->NewSlot(key,SQObjectPtr(_make_field_idx(_defaultvalues.size())));
- _defaultvalues.push_back(m);
- return true;
-}
-
-SQInstance *SQClass::CreateInstance()
-{
- if(!_locked) Lock();
- return SQInstance::Create(_opt_ss(this),this);
-}
-
-SQInteger SQClass::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval)
-{
- SQObjectPtr oval;
- SQInteger idx = _members->Next(false,refpos,outkey,oval);
- if(idx != -1) {
- if(_ismethod(oval)) {
- outval = _methods[_member_idx(oval)].val;
- }
- else {
- SQObjectPtr &o = _defaultvalues[_member_idx(oval)].val;
- outval = _realval(o);
- }
- }
- return idx;
-}
-
-bool SQClass::SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val)
-{
- SQObjectPtr idx;
- if(_members->Get(key,idx)) {
- if(_isfield(idx))
- _defaultvalues[_member_idx(idx)].attrs = val;
- else
- _methods[_member_idx(idx)].attrs = val;
- return true;
- }
- return false;
-}
-
-bool SQClass::GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval)
-{
- SQObjectPtr idx;
- if(_members->Get(key,idx)) {
- outval = (_isfield(idx)?_defaultvalues[_member_idx(idx)].attrs:_methods[_member_idx(idx)].attrs);
- return true;
- }
- return false;
-}
-
-///////////////////////////////////////////////////////////////////////
-void SQInstance::Init(SQSharedState *ss)
-{
- _userpointer = NULL;
- _hook = NULL;
- __ObjAddRef(_class);
- _delegate = _class->_members;
- INIT_CHAIN();
- ADD_TO_CHAIN(&_sharedstate->_gc_chain, this);
-}
-
-SQInstance::SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize)
-{
- _memsize = memsize;
- _class = c;
- SQUnsignedInteger nvalues = _class->_defaultvalues.size();
- for(SQUnsignedInteger n = 0; n < nvalues; n++) {
- new (&_values[n]) SQObjectPtr(_class->_defaultvalues[n].val);
- }
- Init(ss);
-}
-
-SQInstance::SQInstance(SQSharedState *ss, SQInstance *i, SQInteger memsize)
-{
- _memsize = memsize;
- _class = i->_class;
- SQUnsignedInteger nvalues = _class->_defaultvalues.size();
- for(SQUnsignedInteger n = 0; n < nvalues; n++) {
- new (&_values[n]) SQObjectPtr(i->_values[n]);
- }
- Init(ss);
-}
-
-void SQInstance::Finalize()
-{
- SQUnsignedInteger nvalues = _class->_defaultvalues.size();
- __ObjRelease(_class);
- for(SQUnsignedInteger i = 0; i < nvalues; i++) {
- _values[i] = _null_;
- }
-}
-
-SQInstance::~SQInstance()
-{
- REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
- if(_class){ Finalize(); } //if _class is null it was already finalized by the GC
-}
-
-bool SQInstance::GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res)
-{
- if(type(_class->_metamethods[mm]) != OT_NULL) {
- res = _class->_metamethods[mm];
- return true;
- }
- return false;
-}
-
-bool SQInstance::InstanceOf(SQClass *trg)
-{
- SQClass *parent = _class;
- while(parent != NULL) {
- if(parent == trg)
- return true;
- parent = parent->_base;
- }
- return false;
-}
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQCLASS_H_
-#define _SQCLASS_H_
-
-struct SQInstance;
-
-struct SQClassMember {
- SQClassMember(){}
- SQClassMember(const SQClassMember &o) {
- val = o.val;
- attrs = o.attrs;
- }
- SQObjectPtr val;
- SQObjectPtr attrs;
-};
-
-typedef sqvector<SQClassMember> SQClassMemberVec;
-
-#define MEMBER_TYPE_METHOD 0x01000000
-#define MEMBER_TYPE_FIELD 0x02000000
-
-#define _ismethod(o) (_integer(o)&MEMBER_TYPE_METHOD)
-#define _isfield(o) (_integer(o)&MEMBER_TYPE_FIELD)
-#define _make_method_idx(i) ((SQInteger)(MEMBER_TYPE_METHOD|i))
-#define _make_field_idx(i) ((SQInteger)(MEMBER_TYPE_FIELD|i))
-#define _member_type(o) (_integer(o)&0xFF000000)
-#define _member_idx(o) (_integer(o)&0x00FFFFFF)
-
-struct SQClass : public CHAINABLE_OBJ
-{
- SQClass(SQSharedState *ss,SQClass *base);
-public:
- static SQClass* Create(SQSharedState *ss,SQClass *base) {
- SQClass *newclass = (SQClass *)SQ_MALLOC(sizeof(SQClass));
- new (newclass) SQClass(ss, base);
- return newclass;
- }
- ~SQClass();
- bool NewSlot(SQSharedState *ss, const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic);
- bool Get(const SQObjectPtr &key,SQObjectPtr &val) {
- if(_members->Get(key,val)) {
- if(_isfield(val)) {
- SQObjectPtr &o = _defaultvalues[_member_idx(val)].val;
- val = _realval(o);
- }
- else {
- val = _methods[_member_idx(val)].val;
- }
- return true;
- }
- return false;
- }
- bool SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val);
- bool GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval);
- void Lock() { _locked = true; if(_base) _base->Lock(); }
- void Release() {
- if (_hook) { _hook(_typetag,0);}
- sq_delete(this, SQClass);
- }
- void Finalize();
-#ifndef NO_GARBAGE_COLLECTOR
- void Mark(SQCollectable ** );
-#endif
- SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);
- SQInstance *CreateInstance();
- SQTable *_members;
- SQClass *_base;
- SQClassMemberVec _defaultvalues;
- SQClassMemberVec _methods;
- SQObjectPtrVec _metamethods;
- SQObjectPtr _attributes;
- SQUserPointer _typetag;
- SQRELEASEHOOK _hook;
- bool _locked;
- SQInteger _udsize;
-};
-
-#define calcinstancesize(_theclass_) \
- (_theclass_->_udsize + sizeof(SQInstance) + (sizeof(SQObjectPtr)*(_theclass_->_defaultvalues.size()>0?_theclass_->_defaultvalues.size()-1:0)))
-
-struct SQInstance : public SQDelegable
-{
- void Init(SQSharedState *ss);
- SQInstance(SQSharedState *ss, SQClass *c, SQInteger memsize);
- SQInstance(SQSharedState *ss, SQInstance *c, SQInteger memsize);
-public:
- static SQInstance* Create(SQSharedState *ss,SQClass *theclass) {
-
- SQInteger size = calcinstancesize(theclass);
- SQInstance *newinst = (SQInstance *)SQ_MALLOC(size);
- new (newinst) SQInstance(ss, theclass,size);
- if(theclass->_udsize) {
- newinst->_userpointer = ((unsigned char *)newinst) + (size - theclass->_udsize);
- }
- return newinst;
- }
- SQInstance *Clone(SQSharedState *ss)
- {
- SQInteger size = calcinstancesize(_class);
- SQInstance *newinst = (SQInstance *)SQ_MALLOC(size);
- new (newinst) SQInstance(ss, this,size);
- if(_class->_udsize) {
- newinst->_userpointer = ((unsigned char *)newinst) + (size - _class->_udsize);
- }
- return newinst;
- }
- ~SQInstance();
- bool Get(const SQObjectPtr &key,SQObjectPtr &val) {
- if(_class->_members->Get(key,val)) {
- if(_isfield(val)) {
- SQObjectPtr &o = _values[_member_idx(val)];
- val = _realval(o);
- }
- else {
- val = _class->_methods[_member_idx(val)].val;
- }
- return true;
- }
- return false;
- }
- bool Set(const SQObjectPtr &key,const SQObjectPtr &val) {
- SQObjectPtr idx;
- if(_class->_members->Get(key,idx) && _isfield(idx)) {
- _values[_member_idx(idx)] = val;
- return true;
- }
- return false;
- }
- void Release() {
- _uiRef++;
- if (_hook) { _hook(_userpointer,0);}
- _uiRef--;
- if(_uiRef > 0) return;
- SQInteger size = _memsize;
- this->~SQInstance();
- SQ_FREE(this, size);
- }
- void Finalize();
-#ifndef NO_GARBAGE_COLLECTOR
- void Mark(SQCollectable ** );
-#endif
- bool InstanceOf(SQClass *trg);
- bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res);
-
- SQClass *_class;
- SQUserPointer _userpointer;
- SQRELEASEHOOK _hook;
- SQInteger _memsize;
- SQObjectPtr _values[1];
-};
-
-#endif //_SQCLASS_H_
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQCLOSURE_H_
-#define _SQCLOSURE_H_
-
-struct SQFunctionProto;
-
-struct SQClosure : public CHAINABLE_OBJ
-{
-private:
- SQClosure(SQSharedState *ss,SQFunctionProto *func){_function=func; INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);}
-public:
- static SQClosure *Create(SQSharedState *ss,SQFunctionProto *func){
- SQClosure *nc=(SQClosure*)SQ_MALLOC(sizeof(SQClosure));
- new (nc) SQClosure(ss,func);
- return nc;
- }
- void Release(){
- sq_delete(this,SQClosure);
- }
- SQClosure *Clone()
- {
- SQClosure * ret = SQClosure::Create(_opt_ss(this),_funcproto(_function));
- ret->_env = _env;
- ret->_outervalues.copy(_outervalues);
- ret->_defaultparams.copy(_defaultparams);
- return ret;
- }
- ~SQClosure()
- {
- REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
- }
- bool Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write);
- static bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret);
-#ifndef NO_GARBAGE_COLLECTOR
- void Mark(SQCollectable **chain);
- void Finalize(){_outervalues.resize(0); }
-#endif
- SQObjectPtr _env;
- SQObjectPtr _function;
- SQObjectPtrVec _outervalues;
- SQObjectPtrVec _defaultparams;
-};
-//////////////////////////////////////////////
-struct SQGenerator : public CHAINABLE_OBJ
-{
- enum SQGeneratorState{eRunning,eSuspended,eDead};
-private:
- SQGenerator(SQSharedState *ss,SQClosure *closure){_closure=closure;_state=eRunning;_ci._generator=NULL;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);}
-public:
- static SQGenerator *Create(SQSharedState *ss,SQClosure *closure){
- SQGenerator *nc=(SQGenerator*)SQ_MALLOC(sizeof(SQGenerator));
- new (nc) SQGenerator(ss,closure);
- return nc;
- }
- ~SQGenerator()
- {
- REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
- }
- void Kill(){
- _state=eDead;
- _stack.resize(0);
- _closure=_null_;}
- void Release(){
- sq_delete(this,SQGenerator);
- }
- bool Yield(SQVM *v);
- bool Resume(SQVM *v,SQInteger target);
-#ifndef NO_GARBAGE_COLLECTOR
- void Mark(SQCollectable **chain);
- void Finalize(){_stack.resize(0);_closure=_null_;}
-#endif
- SQObjectPtr _closure;
- SQObjectPtrVec _stack;
- SQObjectPtrVec _vargsstack;
- SQVM::CallInfo _ci;
- ExceptionsTraps _etraps;
- SQGeneratorState _state;
-};
-
-struct SQNativeClosure : public CHAINABLE_OBJ
-{
-private:
- SQNativeClosure(SQSharedState *ss,SQFUNCTION func){_function=func;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this); }
-public:
- static SQNativeClosure *Create(SQSharedState *ss,SQFUNCTION func)
- {
- SQNativeClosure *nc=(SQNativeClosure*)SQ_MALLOC(sizeof(SQNativeClosure));
- new (nc) SQNativeClosure(ss,func);
- return nc;
- }
- SQNativeClosure *Clone()
- {
- SQNativeClosure * ret = SQNativeClosure::Create(_opt_ss(this),_function);
- ret->_env = _env;
- ret->_name = _name;
- ret->_outervalues.copy(_outervalues);
- ret->_typecheck.copy(_typecheck);
- ret->_nparamscheck = _nparamscheck;
- return ret;
- }
- ~SQNativeClosure()
- {
- REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
- }
- void Release(){
- sq_delete(this,SQNativeClosure);
- }
-#ifndef NO_GARBAGE_COLLECTOR
- void Mark(SQCollectable **chain);
- void Finalize(){_outervalues.resize(0);}
-#endif
- SQInteger _nparamscheck;
- SQIntVec _typecheck;
- SQObjectPtrVec _outervalues;
- SQObjectPtr _env;
- SQFUNCTION _function;
- SQObjectPtr _name;
-};
-
-
-
-#endif //_SQCLOSURE_H_
+++ /dev/null
-/*
- see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include <stdarg.h>
-#include <setjmp.h>
-#include "sqopcodes.h"
-#include "sqstring.h"
-#include "sqfuncproto.h"
-#include "sqcompiler.h"
-#include "sqfuncstate.h"
-#include "sqlexer.h"
-#include "sqvm.h"
-#include "sqtable.h"
-
-#define DEREF_NO_DEREF -1
-#define DEREF_FIELD -2
-
-struct ExpState
-{
- ExpState()
- {
- _deref = DEREF_NO_DEREF;
- _freevar = false;
- _class_or_delete = false;
- _funcarg = false;
- }
- bool _class_or_delete;
- bool _funcarg;
- bool _freevar;
- SQInteger _deref;
-};
-
-typedef sqvector<ExpState> ExpStateVec;
-
-#define _exst (_expstates.top())
-
-#define BEGIN_BREAKBLE_BLOCK() SQInteger __nbreaks__=_fs->_unresolvedbreaks.size(); \
- SQInteger __ncontinues__=_fs->_unresolvedcontinues.size(); \
- _fs->_breaktargets.push_back(0);_fs->_continuetargets.push_back(0);
-
-#define END_BREAKBLE_BLOCK(continue_target) {__nbreaks__=_fs->_unresolvedbreaks.size()-__nbreaks__; \
- __ncontinues__=_fs->_unresolvedcontinues.size()-__ncontinues__; \
- if(__ncontinues__>0)ResolveContinues(_fs,__ncontinues__,continue_target); \
- if(__nbreaks__>0)ResolveBreaks(_fs,__nbreaks__); \
- _fs->_breaktargets.pop_back();_fs->_continuetargets.pop_back();}
-
-class SQCompiler
-{
-public:
- SQCompiler(SQVM *v, SQLEXREADFUNC rg, SQUserPointer up, const SQChar* sourcename, bool raiseerror, bool lineinfo)
- {
- _vm=v;
- _lex.Init(_ss(v), rg, up,ThrowError,this);
- _sourcename = SQString::Create(_ss(v), sourcename);
- _lineinfo = lineinfo;_raiseerror = raiseerror;
- compilererror = NULL;
- }
- static void ThrowError(void *ud, const SQChar *s) {
- SQCompiler *c = (SQCompiler *)ud;
- c->Error(s);
- }
- void Error(const SQChar *s, ...)
- {
- static SQChar temp[256];
- va_list vl;
- va_start(vl, s);
- scvsprintf(temp, s, vl);
- va_end(vl);
- compilererror = temp;
- longjmp(_errorjmp,1);
- }
- void Lex(){ _token = _lex.Lex();}
- void PushExpState(){ _expstates.push_back(ExpState()); }
- bool IsDerefToken(SQInteger tok)
- {
- switch(tok){
- case _SC('='): case _SC('('): case TK_NEWSLOT:
- case TK_MODEQ: case TK_MULEQ: case TK_DIVEQ: case TK_MINUSEQ: case TK_PLUSEQ: case TK_PLUSPLUS: case TK_MINUSMINUS: return true;
- }
- return false;
- }
- ExpState PopExpState()
- {
- ExpState ret = _expstates.top();
- _expstates.pop_back();
- return ret;
- }
- SQObject Expect(SQInteger tok)
- {
-
- if(_token != tok) {
- if(_token == TK_CONSTRUCTOR && tok == TK_IDENTIFIER) {
- //ret = SQString::Create(_ss(_vm),_SC("constructor"));
- //do nothing
- }
- else {
- const SQChar *etypename;
- if(tok > 255) {
- switch(tok)
- {
- case TK_IDENTIFIER:
- etypename = _SC("IDENTIFIER");
- break;
- case TK_STRING_LITERAL:
- etypename = _SC("STRING_LITERAL");
- break;
- case TK_INTEGER:
- etypename = _SC("INTEGER");
- break;
- case TK_FLOAT:
- etypename = _SC("FLOAT");
- break;
- default:
- etypename = _lex.Tok2Str(tok);
- }
- Error(_SC("expected '%s'"), etypename);
- }
- Error(_SC("expected '%c'"), tok);
- }
- }
- SQObjectPtr ret;
- switch(tok)
- {
- case TK_IDENTIFIER:
- ret = _fs->CreateString(_lex._svalue);
- break;
- case TK_STRING_LITERAL:
- ret = _fs->CreateString(_lex._svalue,_lex._longstr.size()-1);
- break;
- case TK_INTEGER:
- ret = SQObjectPtr(_lex._nvalue);
- break;
- case TK_FLOAT:
- ret = SQObjectPtr(_lex._fvalue);
- break;
- }
- Lex();
- return ret;
- }
- bool IsEndOfStatement() { return ((_lex._prevtoken == _SC('\n')) || (_token == SQUIRREL_EOB) || (_token == _SC('}')) || (_token == _SC(';'))); }
- void OptionalSemicolon()
- {
- if(_token == _SC(';')) { Lex(); return; }
- if(!IsEndOfStatement()) {
- Error(_SC("end of statement expected (; or lf)"));
- }
- }
- void MoveIfCurrentTargetIsLocal() {
- SQInteger trg = _fs->TopTarget();
- if(_fs->IsLocal(trg)) {
- trg = _fs->PopTarget(); //no pops the target and move it
- _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), trg);
- }
- }
- bool Compile(SQObjectPtr &o)
- {
- _debugline = 1;
- _debugop = 0;
-
- SQFuncState funcstate(_ss(_vm), NULL,ThrowError,this);
- funcstate._name = SQString::Create(_ss(_vm), _SC("main"));
- _fs = &funcstate;
- _fs->AddParameter(_fs->CreateString(_SC("this")));
- _fs->_sourcename = _sourcename;
- SQInteger stacksize = _fs->GetStackSize();
- if(setjmp(_errorjmp) == 0) {
- Lex();
- while(_token > 0){
- Statement();
- if(_lex._prevtoken != _SC('}')) OptionalSemicolon();
- }
- CleanStack(stacksize);
- _fs->AddLineInfos(_lex._currentline, _lineinfo, true);
- _fs->AddInstruction(_OP_RETURN, 0xFF);
- _fs->SetStackSize(0);
- o =_fs->BuildProto();
-#ifdef _DEBUG_DUMP
- _fs->Dump(_funcproto(o));
-#endif
- }
- else {
- if(_raiseerror && _ss(_vm)->_compilererrorhandler) {
- _ss(_vm)->_compilererrorhandler(_vm, compilererror, type(_sourcename) == OT_STRING?_stringval(_sourcename):_SC("unknown"),
- _lex._currentline, _lex._currentcolumn);
- }
- _vm->_lasterror = SQString::Create(_ss(_vm), compilererror, -1);
- return false;
- }
- return true;
- }
- void Statements()
- {
- while(_token != _SC('}') && _token != TK_DEFAULT && _token != TK_CASE) {
- Statement();
- if(_lex._prevtoken != _SC('}') && _lex._prevtoken != _SC(';')) OptionalSemicolon();
- }
- }
- void Statement()
- {
- _fs->AddLineInfos(_lex._currentline, _lineinfo);
- switch(_token){
- case _SC(';'): Lex(); break;
- case TK_IF: IfStatement(); break;
- case TK_WHILE: WhileStatement(); break;
- case TK_DO: DoWhileStatement(); break;
- case TK_FOR: ForStatement(); break;
- case TK_FOREACH: ForEachStatement(); break;
- case TK_SWITCH: SwitchStatement(); break;
- case TK_LOCAL: LocalDeclStatement(); break;
- case TK_RETURN:
- case TK_YIELD: {
- SQOpcode op;
- if(_token == TK_RETURN) {
- op = _OP_RETURN;
-
- }
- else {
- op = _OP_YIELD;
- _fs->_bgenerator = true;
- }
- Lex();
- if(!IsEndOfStatement()) {
- SQInteger retexp = _fs->GetCurrentPos()+1;
- CommaExpr();
- if(op == _OP_RETURN && _fs->_traps > 0)
- _fs->AddInstruction(_OP_POPTRAP, _fs->_traps, 0);
- _fs->_returnexp = retexp;
- _fs->AddInstruction(op, 1, _fs->PopTarget());
- }
- else{
- if(op == _OP_RETURN && _fs->_traps > 0)
- _fs->AddInstruction(_OP_POPTRAP, _fs->_traps ,0);
- _fs->_returnexp = -1;
- _fs->AddInstruction(op, 0xFF);
- }
- break;}
- case TK_BREAK:
- if(_fs->_breaktargets.size() <= 0)Error(_SC("'break' has to be in a loop block"));
- if(_fs->_breaktargets.top() > 0){
- _fs->AddInstruction(_OP_POPTRAP, _fs->_breaktargets.top(), 0);
- }
- _fs->AddInstruction(_OP_JMP, 0, -1234);
- _fs->_unresolvedbreaks.push_back(_fs->GetCurrentPos());
- Lex();
- break;
- case TK_CONTINUE:
- if(_fs->_continuetargets.size() <= 0)Error(_SC("'continue' has to be in a loop block"));
- if(_fs->_continuetargets.top() > 0) {
- _fs->AddInstruction(_OP_POPTRAP, _fs->_continuetargets.top(), 0);
- }
- _fs->AddInstruction(_OP_JMP, 0, -1234);
- _fs->_unresolvedcontinues.push_back(_fs->GetCurrentPos());
- Lex();
- break;
- case TK_FUNCTION:
- FunctionStatement();
- break;
- case TK_CLASS:
- ClassStatement();
- break;
- case TK_ENUM:
- EnumStatement();
- break;
- case _SC('{'):{
- SQInteger stacksize = _fs->GetStackSize();
- Lex();
- Statements();
- Expect(_SC('}'));
- _fs->SetStackSize(stacksize);
- }
- break;
- case TK_TRY:
- TryCatchStatement();
- break;
- case TK_THROW:
- Lex();
- CommaExpr();
- _fs->AddInstruction(_OP_THROW, _fs->PopTarget());
- break;
- case TK_CONST:
- {
- Lex();
- SQObject id = Expect(TK_IDENTIFIER);
- Expect('=');
- SQObject val = ExpectScalar();
- OptionalSemicolon();
- SQTable *enums = _table(_ss(_vm)->_consts);
- SQObjectPtr strongid = id;
- enums->NewSlot(strongid,SQObjectPtr(val));
- strongid.Null();
- }
- break;
- default:
- CommaExpr();
- _fs->PopTarget();
- break;
- }
- _fs->SnoozeOpt();
- }
- void EmitDerefOp(SQOpcode op)
- {
- SQInteger val = _fs->PopTarget();
- SQInteger key = _fs->PopTarget();
- SQInteger src = _fs->PopTarget();
- _fs->AddInstruction(op,_fs->PushTarget(),src,key,val);
- }
- void Emit2ArgsOP(SQOpcode op, SQInteger p3 = 0)
- {
- SQInteger p2 = _fs->PopTarget(); //src in OP_GET
- SQInteger p1 = _fs->PopTarget(); //key in OP_GET
- _fs->AddInstruction(op,_fs->PushTarget(), p1, p2, p3);
- }
- void EmitCompoundArith(SQInteger tok,bool deref)
- {
- SQInteger oper;
- switch(tok){
- case TK_MINUSEQ: oper = '-'; break;
- case TK_PLUSEQ: oper = '+'; break;
- case TK_MULEQ: oper = '*'; break;
- case TK_DIVEQ: oper = '/'; break;
- case TK_MODEQ: oper = '%'; break;
- default: oper = 0; //shut up compiler
- assert(0); break;
- };
- if(deref) {
- SQInteger val = _fs->PopTarget();
- SQInteger key = _fs->PopTarget();
- SQInteger src = _fs->PopTarget();
- //mixes dest obj and source val in the arg1(hack?)
- _fs->AddInstruction(_OP_COMPARITH,_fs->PushTarget(),(src<<16)|val,key,oper);
- }
- else {
- Emit2ArgsOP(_OP_COMPARITHL, oper);
- }
- }
- void CommaExpr()
- {
- for(Expression();_token == ',';_fs->PopTarget(), Lex(), CommaExpr());
- }
- ExpState Expression(bool funcarg = false)
- {
- PushExpState();
- _exst._class_or_delete = false;
- _exst._funcarg = funcarg;
- LogicalOrExp();
- switch(_token) {
- case _SC('='):
- case TK_NEWSLOT:
- case TK_MINUSEQ:
- case TK_PLUSEQ:
- case TK_MULEQ:
- case TK_DIVEQ:
- case TK_MODEQ:
- {
- SQInteger op = _token;
- SQInteger ds = _exst._deref;
- bool freevar = _exst._freevar;
- if(ds == DEREF_NO_DEREF) Error(_SC("can't assign expression"));
- Lex(); Expression();
-
- switch(op){
- case TK_NEWSLOT:
- if(freevar) Error(_SC("free variables cannot be modified"));
- if(ds == DEREF_FIELD)
- EmitDerefOp(_OP_NEWSLOT);
- else //if _derefstate != DEREF_NO_DEREF && DEREF_FIELD so is the index of a local
- Error(_SC("can't 'create' a local slot"));
- break;
- case _SC('='): //ASSIGN
- if(freevar) Error(_SC("free variables cannot be modified"));
- if(ds == DEREF_FIELD)
- EmitDerefOp(_OP_SET);
- else {//if _derefstate != DEREF_NO_DEREF && DEREF_FIELD so is the index of a local
- SQInteger p2 = _fs->PopTarget(); //src in OP_GET
- SQInteger p1 = _fs->TopTarget(); //key in OP_GET
- _fs->AddInstruction(_OP_MOVE, p1, p2);
- }
- break;
- case TK_MINUSEQ:
- case TK_PLUSEQ:
- case TK_MULEQ:
- case TK_DIVEQ:
- case TK_MODEQ:
- EmitCompoundArith(op,ds == DEREF_FIELD);
- break;
- }
- }
- break;
- case _SC('?'): {
- Lex();
- _fs->AddInstruction(_OP_JZ, _fs->PopTarget());
- SQInteger jzpos = _fs->GetCurrentPos();
- SQInteger trg = _fs->PushTarget();
- Expression();
- SQInteger first_exp = _fs->PopTarget();
- if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp);
- SQInteger endfirstexp = _fs->GetCurrentPos();
- _fs->AddInstruction(_OP_JMP, 0, 0);
- Expect(_SC(':'));
- SQInteger jmppos = _fs->GetCurrentPos();
- Expression();
- SQInteger second_exp = _fs->PopTarget();
- if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp);
- _fs->SetIntructionParam(jmppos, 1, _fs->GetCurrentPos() - jmppos);
- _fs->SetIntructionParam(jzpos, 1, endfirstexp - jzpos + 1);
- _fs->SnoozeOpt();
- }
- break;
- }
- return PopExpState();
- }
- void BIN_EXP(SQOpcode op, void (SQCompiler::*f)(void),SQInteger op3 = 0)
- {
- Lex(); (this->*f)();
- SQInteger op1 = _fs->PopTarget();SQInteger op2 = _fs->PopTarget();
- _fs->AddInstruction(op, _fs->PushTarget(), op1, op2, op3);
- }
- void LogicalOrExp()
- {
- LogicalAndExp();
- for(;;) if(_token == TK_OR) {
- SQInteger first_exp = _fs->PopTarget();
- SQInteger trg = _fs->PushTarget();
- _fs->AddInstruction(_OP_OR, trg, 0, first_exp, 0);
- SQInteger jpos = _fs->GetCurrentPos();
- if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp);
- Lex(); LogicalOrExp();
- _fs->SnoozeOpt();
- SQInteger second_exp = _fs->PopTarget();
- if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp);
- _fs->SnoozeOpt();
- _fs->SetIntructionParam(jpos, 1, (_fs->GetCurrentPos() - jpos));
- break;
- }else return;
- }
- void LogicalAndExp()
- {
- BitwiseOrExp();
- for(;;) switch(_token) {
- case TK_AND: {
- SQInteger first_exp = _fs->PopTarget();
- SQInteger trg = _fs->PushTarget();
- _fs->AddInstruction(_OP_AND, trg, 0, first_exp, 0);
- SQInteger jpos = _fs->GetCurrentPos();
- if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp);
- Lex(); LogicalAndExp();
- _fs->SnoozeOpt();
- SQInteger second_exp = _fs->PopTarget();
- if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp);
- _fs->SnoozeOpt();
- _fs->SetIntructionParam(jpos, 1, (_fs->GetCurrentPos() - jpos));
- break;
- }
- case TK_IN: BIN_EXP(_OP_EXISTS, &SQCompiler::BitwiseOrExp); break;
- case TK_INSTANCEOF: BIN_EXP(_OP_INSTANCEOF, &SQCompiler::BitwiseOrExp); break;
- default:
- return;
- }
- }
- void BitwiseOrExp()
- {
- BitwiseXorExp();
- for(;;) if(_token == _SC('|'))
- {BIN_EXP(_OP_BITW, &SQCompiler::BitwiseXorExp,BW_OR);
- }else return;
- }
- void BitwiseXorExp()
- {
- BitwiseAndExp();
- for(;;) if(_token == _SC('^'))
- {BIN_EXP(_OP_BITW, &SQCompiler::BitwiseAndExp,BW_XOR);
- }else return;
- }
- void BitwiseAndExp()
- {
- CompExp();
- for(;;) if(_token == _SC('&'))
- {BIN_EXP(_OP_BITW, &SQCompiler::CompExp,BW_AND);
- }else return;
- }
- void CompExp()
- {
- ShiftExp();
- for(;;) switch(_token) {
- case TK_EQ: BIN_EXP(_OP_EQ, &SQCompiler::ShiftExp); break;
- case _SC('>'): BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_G); break;
- case _SC('<'): BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_L); break;
- case TK_GE: BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_GE); break;
- case TK_LE: BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_LE); break;
- case TK_NE: BIN_EXP(_OP_NE, &SQCompiler::ShiftExp); break;
- default: return;
- }
- }
- void ShiftExp()
- {
- PlusExp();
- for(;;) switch(_token) {
- case TK_USHIFTR: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_USHIFTR); break;
- case TK_SHIFTL: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_SHIFTL); break;
- case TK_SHIFTR: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_SHIFTR); break;
- default: return;
- }
- }
- void PlusExp()
- {
- MultExp();
- for(;;) switch(_token) {
- case _SC('+'): case _SC('-'):
- BIN_EXP(_OP_ARITH, &SQCompiler::MultExp,_token); break;
- default: return;
- }
- }
-
- void MultExp()
- {
- PrefixedExpr();
- for(;;) switch(_token) {
- case _SC('*'): case _SC('/'): case _SC('%'):
- BIN_EXP(_OP_ARITH, &SQCompiler::PrefixedExpr,_token); break;
- default: return;
- }
- }
- //if 'pos' != -1 the previous variable is a local variable
- void PrefixedExpr()
- {
- SQInteger pos = Factor();
- for(;;) {
- switch(_token) {
- case _SC('.'): {
- pos = -1;
- Lex();
- if(_token == TK_PARENT) {
- Lex();
- if(!NeedGet())
- Error(_SC("parent cannot be set"));
- SQInteger src = _fs->PopTarget();
- _fs->AddInstruction(_OP_GETPARENT, _fs->PushTarget(), src);
- }
- else {
- _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(Expect(TK_IDENTIFIER)));
- if(NeedGet()) Emit2ArgsOP(_OP_GET);
- }
- _exst._deref = DEREF_FIELD;
- _exst._freevar = false;
- }
- break;
- case _SC('['):
- if(_lex._prevtoken == _SC('\n')) Error(_SC("cannot brake deref/or comma needed after [exp]=exp slot declaration"));
- Lex(); Expression(); Expect(_SC(']'));
- pos = -1;
- if(NeedGet()) Emit2ArgsOP(_OP_GET);
- _exst._deref = DEREF_FIELD;
- _exst._freevar = false;
- break;
- case TK_MINUSMINUS:
- case TK_PLUSPLUS:
- if(_exst._deref != DEREF_NO_DEREF && !IsEndOfStatement()) {
- SQInteger tok = _token; Lex();
- if(pos < 0)
- Emit2ArgsOP(_OP_PINC,tok == TK_MINUSMINUS?-1:1);
- else {//if _derefstate != DEREF_NO_DEREF && DEREF_FIELD so is the index of a local
- SQInteger src = _fs->PopTarget();
- _fs->AddInstruction(_OP_PINCL, _fs->PushTarget(), src, 0, tok == TK_MINUSMINUS?-1:1);
- }
-
- }
- return;
- break;
- case _SC('('):
- {
- if(_exst._deref != DEREF_NO_DEREF) {
- if(pos<0) {
- SQInteger key = _fs->PopTarget(); //key
- SQInteger table = _fs->PopTarget(); //table etc...
- SQInteger closure = _fs->PushTarget();
- SQInteger ttarget = _fs->PushTarget();
- _fs->AddInstruction(_OP_PREPCALL, closure, key, table, ttarget);
- }
- else{
- _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), 0);
- }
- }
- else
- _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), 0);
- _exst._deref = DEREF_NO_DEREF;
- Lex();
- FunctionCallArgs();
- }
- break;
- default: return;
- }
- }
- }
- SQInteger Factor()
- {
- switch(_token)
- {
- case TK_STRING_LITERAL: {
- //SQObjectPtr id(SQString::Create(_ss(_vm), _lex._svalue,_lex._longstr.size()-1));
- _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(_fs->CreateString(_lex._svalue,_lex._longstr.size()-1)));
- Lex();
- }
- break;
- case TK_VARGC: Lex(); _fs->AddInstruction(_OP_VARGC, _fs->PushTarget()); break;
- case TK_VARGV: { Lex();
- Expect(_SC('['));
- Expression();
- Expect(_SC(']'));
- SQInteger src = _fs->PopTarget();
- _fs->AddInstruction(_OP_GETVARGV, _fs->PushTarget(), src);
- }
- break;
- case TK_IDENTIFIER:
- case TK_CONSTRUCTOR:
- case TK_THIS:{
- _exst._freevar = false;
- SQObject id;
- SQObject constant;
- switch(_token) {
- case TK_IDENTIFIER: id = _fs->CreateString(_lex._svalue); break;
- case TK_THIS: id = _fs->CreateString(_SC("this")); break;
- case TK_CONSTRUCTOR: id = _fs->CreateString(_SC("constructor")); break;
- }
- SQInteger pos = -1;
- Lex();
- if((pos = _fs->GetLocalVariable(id)) == -1) {
- //checks if is a free variable
- if((pos = _fs->GetOuterVariable(id)) != -1) {
- _exst._deref = _fs->PushTarget();
- _fs->AddInstruction(_OP_LOADFREEVAR, _exst._deref ,pos);
- _exst._freevar = true;
- }
- else if(_fs->IsConstant(id,constant)) { //line 634
- SQObjectPtr constval;
- SQObject constid;
- if(type(constant) == OT_TABLE) {
- Expect('.'); constid = Expect(TK_IDENTIFIER);
- if(!_table(constant)->Get(constid,constval)) {
- constval.Null();
- Error(_SC("invalid constant [%s.%s]"), _stringval(id),_stringval(constid));
- }
- }
- else {
- constval = constant;
- }
- _exst._deref = _fs->PushTarget();
- SQObjectType ctype = type(constval);
- if(ctype == OT_INTEGER && (_integer(constval) & (~0x7FFFFFFF)) == 0) {
- _fs->AddInstruction(_OP_LOADINT, _exst._deref,_integer(constval));
- }
- else if(ctype == OT_FLOAT && sizeof(SQFloat) == sizeof(SQInt32)) {
- SQFloat f = _float(constval);
- _fs->AddInstruction(_OP_LOADFLOAT, _exst._deref,*((SQInt32 *)&f));
- }
- else {
- _fs->AddInstruction(_OP_LOAD, _exst._deref, _fs->GetConstant(constval));
- }
-
- _exst._freevar = true;
- }
- else {
- _fs->PushTarget(0);
- _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));
- if(NeedGet()) Emit2ArgsOP(_OP_GET);
- _exst._deref = DEREF_FIELD;
- }
- }
-
- else{
- _fs->PushTarget(pos);
- _exst._deref = pos;
- }
- return _exst._deref;
- }
- break;
- case TK_PARENT: Lex();_fs->AddInstruction(_OP_GETPARENT, _fs->PushTarget(), 0); break;
- case TK_DOUBLE_COLON: // "::"
- _fs->AddInstruction(_OP_LOADROOTTABLE, _fs->PushTarget());
- _exst._deref = DEREF_FIELD;
- _token = _SC('.'); //hack
- return -1;
- break;
- case TK_NULL:
- _fs->AddInstruction(_OP_LOADNULLS, _fs->PushTarget(),1);
- Lex();
- break;
- case TK_INTEGER: {
- if((_lex._nvalue & (~0x7FFFFFFF)) == 0) { //does it fit in 32 bits?
- _fs->AddInstruction(_OP_LOADINT, _fs->PushTarget(),_lex._nvalue);
- }
- else {
- _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetNumericConstant(_lex._nvalue));
- }
- Lex();
- }
- break;
- case TK_FLOAT:
- if(sizeof(SQFloat) == sizeof(SQInt32)) {
- _fs->AddInstruction(_OP_LOADFLOAT, _fs->PushTarget(),*((SQInt32 *)&_lex._fvalue));
- }
- else {
- _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetNumericConstant(_lex._fvalue));
- }
- Lex();
- break;
- case TK_TRUE: case TK_FALSE:
- _fs->AddInstruction(_OP_LOADBOOL, _fs->PushTarget(),_token == TK_TRUE?1:0);
- Lex();
- break;
- case _SC('['): {
- _fs->AddInstruction(_OP_NEWARRAY, _fs->PushTarget());
- SQInteger apos = _fs->GetCurrentPos(),key = 0;
- Lex();
- while(_token != _SC(']')) {
- Expression();
- if(_token == _SC(',')) Lex();
- SQInteger val = _fs->PopTarget();
- SQInteger array = _fs->TopTarget();
- _fs->AddInstruction(_OP_APPENDARRAY, array, val);
- key++;
- }
- _fs->SetIntructionParam(apos, 1, key);
- Lex();
- }
- break;
- case _SC('{'):{
- _fs->AddInstruction(_OP_NEWTABLE, _fs->PushTarget());
- Lex();ParseTableOrClass(_SC(','));
- }
- break;
- case TK_FUNCTION: FunctionExp(_token);break;
- case TK_CLASS: Lex(); ClassExp();break;
- case _SC('-'): UnaryOP(_OP_NEG); break;
- case _SC('!'): UnaryOP(_OP_NOT); break;
- case _SC('~'): UnaryOP(_OP_BWNOT); break;
- case TK_TYPEOF : UnaryOP(_OP_TYPEOF); break;
- case TK_RESUME : UnaryOP(_OP_RESUME); break;
- case TK_CLONE : UnaryOP(_OP_CLONE); break;
- case TK_MINUSMINUS :
- case TK_PLUSPLUS :PrefixIncDec(_token); break;
- case TK_DELETE : DeleteExpr(); break;
- case TK_DELEGATE : DelegateExpr(); break;
- case _SC('('): Lex(); CommaExpr(); Expect(_SC(')'));
- break;
- default: Error(_SC("expression expected"));
- }
- return -1;
- }
- void UnaryOP(SQOpcode op)
- {
- Lex(); PrefixedExpr();
- SQInteger src = _fs->PopTarget();
- _fs->AddInstruction(op, _fs->PushTarget(), src);
- }
- bool NeedGet()
- {
- switch(_token) {
- case _SC('='): case _SC('('): case TK_NEWSLOT: case TK_PLUSPLUS: case TK_MINUSMINUS:
- case TK_PLUSEQ: case TK_MINUSEQ: case TK_MULEQ: case TK_DIVEQ: case TK_MODEQ:
- return false;
- }
- return (!_exst._class_or_delete) || (_exst._class_or_delete && (_token == _SC('.') || _token == _SC('[')));
- }
-
- void FunctionCallArgs()
- {
- SQInteger nargs = 1;//this
- while(_token != _SC(')')) {
- Expression(true);
- MoveIfCurrentTargetIsLocal();
- nargs++;
- if(_token == _SC(',')){
- Lex();
- if(_token == ')') Error(_SC("expression expected, found ')'"));
- }
- }
- Lex();
- for(SQInteger i = 0; i < (nargs - 1); i++) _fs->PopTarget();
- SQInteger stackbase = _fs->PopTarget();
- SQInteger closure = _fs->PopTarget();
- _fs->AddInstruction(_OP_CALL, _fs->PushTarget(), closure, stackbase, nargs);
- }
- void ParseTableOrClass(SQInteger separator,SQInteger terminator = '}')
- {
- SQInteger tpos = _fs->GetCurrentPos(),nkeys = 0;
-
- while(_token != terminator) {
- bool hasattrs = false;
- bool isstatic = false;
- //check if is an attribute
- if(separator == ';') {
- if(_token == TK_ATTR_OPEN) {
- _fs->AddInstruction(_OP_NEWTABLE, _fs->PushTarget()); Lex();
- ParseTableOrClass(',',TK_ATTR_CLOSE);
- hasattrs = true;
- }
- if(_token == TK_STATIC) {
- isstatic = true;
- Lex();
- }
- }
- switch(_token) {
- case TK_FUNCTION:
- case TK_CONSTRUCTOR:{
- SQInteger tk = _token;
- Lex();
- SQObject id = tk == TK_FUNCTION ? Expect(TK_IDENTIFIER) : _fs->CreateString(_SC("constructor"));
- Expect(_SC('('));
- _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));
- CreateFunction(id);
- _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, 0);
- }
- break;
- case _SC('['):
- Lex(); CommaExpr(); Expect(_SC(']'));
- Expect(_SC('=')); Expression();
- break;
- default :
- _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(Expect(TK_IDENTIFIER)));
- Expect(_SC('=')); Expression();
- }
-
- if(_token == separator) Lex();//optional comma/semicolon
- nkeys++;
- SQInteger val = _fs->PopTarget();
- SQInteger key = _fs->PopTarget();
- SQInteger attrs = hasattrs ? _fs->PopTarget():-1;
- assert(hasattrs && attrs == key-1 || !hasattrs);
- unsigned char flags = (hasattrs?NEW_SLOT_ATTRIBUTES_FLAG:0)|(isstatic?NEW_SLOT_STATIC_FLAG:0);
- SQInteger table = _fs->TopTarget(); //<<BECAUSE OF THIS NO COMMON EMIT FUNC IS POSSIBLE
- _fs->AddInstruction(_OP_NEWSLOTA, flags, table, key, val);
- //_fs->PopTarget();
- }
- if(separator == _SC(',')) //hack recognizes a table from the separator
- _fs->SetIntructionParam(tpos, 1, nkeys);
- Lex();
- }
- void LocalDeclStatement()
- {
- SQObject varname;
- do {
- Lex(); varname = Expect(TK_IDENTIFIER);
- if(_token == _SC('=')) {
- Lex(); Expression();
- SQInteger src = _fs->PopTarget();
- SQInteger dest = _fs->PushTarget();
- if(dest != src) _fs->AddInstruction(_OP_MOVE, dest, src);
- }
- else{
- _fs->AddInstruction(_OP_LOADNULLS, _fs->PushTarget(),1);
- }
- _fs->PopTarget();
- _fs->PushLocalVariable(varname);
-
- } while(_token == _SC(','));
- }
- void IfStatement()
- {
- SQInteger jmppos;
- bool haselse = false;
- Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')'));
- _fs->AddInstruction(_OP_JZ, _fs->PopTarget());
- SQInteger jnepos = _fs->GetCurrentPos();
- SQInteger stacksize = _fs->GetStackSize();
-
- Statement();
- //
- if(_token != _SC('}') && _token != TK_ELSE) OptionalSemicolon();
-
- CleanStack(stacksize);
- SQInteger endifblock = _fs->GetCurrentPos();
- if(_token == TK_ELSE){
- haselse = true;
- stacksize = _fs->GetStackSize();
- _fs->AddInstruction(_OP_JMP);
- jmppos = _fs->GetCurrentPos();
- Lex();
- Statement(); OptionalSemicolon();
- CleanStack(stacksize);
- _fs->SetIntructionParam(jmppos, 1, _fs->GetCurrentPos() - jmppos);
- }
- _fs->SetIntructionParam(jnepos, 1, endifblock - jnepos + (haselse?1:0));
- }
- void WhileStatement()
- {
- SQInteger jzpos, jmppos;
- SQInteger stacksize = _fs->GetStackSize();
- jmppos = _fs->GetCurrentPos();
- Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')'));
-
- BEGIN_BREAKBLE_BLOCK();
- _fs->AddInstruction(_OP_JZ, _fs->PopTarget());
- jzpos = _fs->GetCurrentPos();
- stacksize = _fs->GetStackSize();
-
- Statement();
-
- CleanStack(stacksize);
- _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1);
- _fs->SetIntructionParam(jzpos, 1, _fs->GetCurrentPos() - jzpos);
-
- END_BREAKBLE_BLOCK(jmppos);
- }
- void DoWhileStatement()
- {
- Lex();
- SQInteger jzpos = _fs->GetCurrentPos();
- SQInteger stacksize = _fs->GetStackSize();
- BEGIN_BREAKBLE_BLOCK()
- Statement();
- CleanStack(stacksize);
- Expect(TK_WHILE);
- SQInteger continuetrg = _fs->GetCurrentPos();
- Expect(_SC('(')); CommaExpr(); Expect(_SC(')'));
- _fs->AddInstruction(_OP_JNZ, _fs->PopTarget(), jzpos - _fs->GetCurrentPos() - 1);
- END_BREAKBLE_BLOCK(continuetrg);
- }
- void ForStatement()
- {
- Lex();
- SQInteger stacksize = _fs->GetStackSize();
- Expect(_SC('('));
- if(_token == TK_LOCAL) LocalDeclStatement();
- else if(_token != _SC(';')){
- CommaExpr();
- _fs->PopTarget();
- }
- Expect(_SC(';'));
- _fs->SnoozeOpt();
- SQInteger jmppos = _fs->GetCurrentPos();
- SQInteger jzpos = -1;
- if(_token != _SC(';')) { CommaExpr(); _fs->AddInstruction(_OP_JZ, _fs->PopTarget()); jzpos = _fs->GetCurrentPos(); }
- Expect(_SC(';'));
- _fs->SnoozeOpt();
- SQInteger expstart = _fs->GetCurrentPos() + 1;
- if(_token != _SC(')')) {
- CommaExpr();
- _fs->PopTarget();
- }
- Expect(_SC(')'));
- _fs->SnoozeOpt();
- SQInteger expend = _fs->GetCurrentPos();
- SQInteger expsize = (expend - expstart) + 1;
- SQInstructionVec exp;
- if(expsize > 0) {
- for(SQInteger i = 0; i < expsize; i++)
- exp.push_back(_fs->GetInstruction(expstart + i));
- _fs->PopInstructions(expsize);
- }
- BEGIN_BREAKBLE_BLOCK()
- Statement();
- SQInteger continuetrg = _fs->GetCurrentPos();
- if(expsize > 0) {
- for(SQInteger i = 0; i < expsize; i++)
- _fs->AddInstruction(exp[i]);
- }
- _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1, 0);
- if(jzpos> 0) _fs->SetIntructionParam(jzpos, 1, _fs->GetCurrentPos() - jzpos);
- CleanStack(stacksize);
-
- END_BREAKBLE_BLOCK(continuetrg);
- }
- void ForEachStatement()
- {
- SQObject idxname, valname;
- Lex(); Expect(_SC('(')); valname = Expect(TK_IDENTIFIER);
- if(_token == _SC(',')) {
- idxname = valname;
- Lex(); valname = Expect(TK_IDENTIFIER);
- }
- else{
- idxname = _fs->CreateString(_SC("@INDEX@"));
- }
- Expect(TK_IN);
-
- //save the stack size
- SQInteger stacksize = _fs->GetStackSize();
- //put the table in the stack(evaluate the table expression)
- Expression(); Expect(_SC(')'));
- SQInteger container = _fs->TopTarget();
- //push the index local var
- SQInteger indexpos = _fs->PushLocalVariable(idxname);
- _fs->AddInstruction(_OP_LOADNULLS, indexpos,1);
- //push the value local var
- SQInteger valuepos = _fs->PushLocalVariable(valname);
- _fs->AddInstruction(_OP_LOADNULLS, valuepos,1);
- //push reference index
- SQInteger itrpos = _fs->PushLocalVariable(_fs->CreateString(_SC("@ITERATOR@"))); //use invalid id to make it inaccessible
- _fs->AddInstruction(_OP_LOADNULLS, itrpos,1);
- SQInteger jmppos = _fs->GetCurrentPos();
- _fs->AddInstruction(_OP_FOREACH, container, 0, indexpos);
- SQInteger foreachpos = _fs->GetCurrentPos();
- _fs->AddInstruction(_OP_POSTFOREACH, container, 0, indexpos);
- //generate the statement code
- BEGIN_BREAKBLE_BLOCK()
- Statement();
- _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1);
- _fs->SetIntructionParam(foreachpos, 1, _fs->GetCurrentPos() - foreachpos);
- _fs->SetIntructionParam(foreachpos + 1, 1, _fs->GetCurrentPos() - foreachpos);
- //restore the local variable stack(remove index,val and ref idx)
- CleanStack(stacksize);
- END_BREAKBLE_BLOCK(foreachpos - 1);
- }
- void SwitchStatement()
- {
- Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')'));
- Expect(_SC('{'));
- SQInteger expr = _fs->TopTarget();
- bool bfirst = true;
- SQInteger tonextcondjmp = -1;
- SQInteger skipcondjmp = -1;
- SQInteger __nbreaks__ = _fs->_unresolvedbreaks.size();
- _fs->_breaktargets.push_back(0);
- while(_token == TK_CASE) {
- //_fs->AddLineInfos(_lex._currentline, _lineinfo); think about this one
- if(!bfirst) {
- _fs->AddInstruction(_OP_JMP, 0, 0);
- skipcondjmp = _fs->GetCurrentPos();
- _fs->SetIntructionParam(tonextcondjmp, 1, _fs->GetCurrentPos() - tonextcondjmp);
- }
- //condition
- Lex(); Expression(); Expect(_SC(':'));
- SQInteger trg = _fs->PopTarget();
- _fs->AddInstruction(_OP_EQ, trg, trg, expr);
- _fs->AddInstruction(_OP_JZ, trg, 0);
- //end condition
- if(skipcondjmp != -1) {
- _fs->SetIntructionParam(skipcondjmp, 1, (_fs->GetCurrentPos() - skipcondjmp));
- }
- tonextcondjmp = _fs->GetCurrentPos();
- SQInteger stacksize = _fs->GetStackSize();
- Statements();
- _fs->SetStackSize(stacksize);
- bfirst = false;
- }
- if(tonextcondjmp != -1)
- _fs->SetIntructionParam(tonextcondjmp, 1, _fs->GetCurrentPos() - tonextcondjmp);
- if(_token == TK_DEFAULT) {
- // _fs->AddLineInfos(_lex._currentline, _lineinfo);
- Lex(); Expect(_SC(':'));
- SQInteger stacksize = _fs->GetStackSize();
- Statements();
- _fs->SetStackSize(stacksize);
- }
- Expect(_SC('}'));
- _fs->PopTarget();
- __nbreaks__ = _fs->_unresolvedbreaks.size() - __nbreaks__;
- if(__nbreaks__ > 0)ResolveBreaks(_fs, __nbreaks__);
- _fs->_breaktargets.pop_back();
-
- }
- void FunctionStatement()
- {
- SQObject id;
- Lex(); id = Expect(TK_IDENTIFIER);
- _fs->PushTarget(0);
- _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));
- if(_token == TK_DOUBLE_COLON) Emit2ArgsOP(_OP_GET);
-
- while(_token == TK_DOUBLE_COLON) {
- Lex();
- id = Expect(TK_IDENTIFIER);
- _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));
- if(_token == TK_DOUBLE_COLON) Emit2ArgsOP(_OP_GET);
- }
- Expect(_SC('('));
- CreateFunction(id);
- _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, 0);
- EmitDerefOp(_OP_NEWSLOT);
- _fs->PopTarget();
- }
- void ClassStatement()
- {
- ExpState es;
- Lex(); PushExpState();
- _exst._class_or_delete = true;
- _exst._funcarg = false;
- PrefixedExpr();
- es = PopExpState();
- if(es._deref == DEREF_NO_DEREF) Error(_SC("invalid class name"));
- if(es._deref == DEREF_FIELD) {
- ClassExp();
- EmitDerefOp(_OP_NEWSLOT);
- _fs->PopTarget();
- }
- else Error(_SC("cannot create a class in a local with the syntax(class <local>)"));
- }
- SQObject ExpectScalar()
- {
- SQObject val;
- switch(_token) {
- case TK_INTEGER:
- val._type = OT_INTEGER;
- val._unVal.nInteger = _lex._nvalue;
- break;
- case TK_FLOAT:
- val._type = OT_FLOAT;
- val._unVal.fFloat = _lex._fvalue;
- break;
- case TK_STRING_LITERAL:
- val = _fs->CreateString(_lex._svalue,_lex._longstr.size()-1);
- break;
- case '-':
- Lex();
- switch(_token)
- {
- case TK_INTEGER:
- val._type = OT_INTEGER;
- val._unVal.nInteger = -_lex._nvalue;
- break;
- case TK_FLOAT:
- val._type = OT_FLOAT;
- val._unVal.fFloat = -_lex._fvalue;
- break;
- default:
- Error(_SC("scalar expected : integer,float"));
- }
- break;
- default:
- Error(_SC("scalar expected : integer,float or string"));
- }
- Lex();
- return val;
- }
- void EnumStatement()
- {
-
- Lex();
- SQObject id = Expect(TK_IDENTIFIER);
- Expect(_SC('{'));
-
- SQObject table = _fs->CreateTable();
- SQInteger nval = 0;
- while(_token != _SC('}')) {
- SQObject key = Expect(TK_IDENTIFIER);
- SQObject val;
- if(_token == _SC('=')) {
- Lex();
- val = ExpectScalar();
- }
- else {
- val._type = OT_INTEGER;
- val._unVal.nInteger = nval++;
- }
- _table(table)->NewSlot(SQObjectPtr(key),SQObjectPtr(val));
- if(_token == ',') Lex();
- }
- SQTable *enums = _table(_ss(_vm)->_consts);
- SQObjectPtr strongid = id;
- /*SQObjectPtr dummy;
- if(enums->Get(strongid,dummy)) {
- dummy.Null(); strongid.Null();
- Error(_SC("enumeration already exists"));
- }*/
- enums->NewSlot(SQObjectPtr(strongid),SQObjectPtr(table));
- strongid.Null();
- Lex();
-
- }
- void TryCatchStatement()
- {
- SQObject exid;
- Lex();
- _fs->AddInstruction(_OP_PUSHTRAP,0,0);
- _fs->_traps++;
- if(_fs->_breaktargets.size()) _fs->_breaktargets.top()++;
- if(_fs->_continuetargets.size()) _fs->_continuetargets.top()++;
- SQInteger trappos = _fs->GetCurrentPos();
- Statement();
- _fs->_traps--;
- _fs->AddInstruction(_OP_POPTRAP, 1, 0);
- if(_fs->_breaktargets.size()) _fs->_breaktargets.top()--;
- if(_fs->_continuetargets.size()) _fs->_continuetargets.top()--;
- _fs->AddInstruction(_OP_JMP, 0, 0);
- SQInteger jmppos = _fs->GetCurrentPos();
- _fs->SetIntructionParam(trappos, 1, (_fs->GetCurrentPos() - trappos));
- Expect(TK_CATCH); Expect(_SC('(')); exid = Expect(TK_IDENTIFIER); Expect(_SC(')'));
- SQInteger stacksize = _fs->GetStackSize();
- SQInteger ex_target = _fs->PushLocalVariable(exid);
- _fs->SetIntructionParam(trappos, 0, ex_target);
- Statement();
- _fs->SetIntructionParams(jmppos, 0, (_fs->GetCurrentPos() - jmppos), 0);
- CleanStack(stacksize);
- }
- void FunctionExp(SQInteger ftype)
- {
- Lex(); Expect(_SC('('));
- CreateFunction(_null_);
- _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, ftype == TK_FUNCTION?0:1);
- }
- void ClassExp()
- {
- SQInteger base = -1;
- SQInteger attrs = -1;
- if(_token == TK_EXTENDS) {
- Lex(); Expression();
- base = _fs->TopTarget();
- }
- if(_token == TK_ATTR_OPEN) {
- Lex();
- _fs->AddInstruction(_OP_NEWTABLE, _fs->PushTarget());
- ParseTableOrClass(_SC(','),TK_ATTR_CLOSE);
- attrs = _fs->TopTarget();
- }
- Expect(_SC('{'));
- if(attrs != -1) _fs->PopTarget();
- if(base != -1) _fs->PopTarget();
- _fs->AddInstruction(_OP_CLASS, _fs->PushTarget(), base, attrs);
- ParseTableOrClass(_SC(';'));
- }
- void DelegateExpr()
- {
- Lex(); CommaExpr();
- Expect(_SC(':'));
- CommaExpr();
- SQInteger table = _fs->PopTarget(), delegate = _fs->PopTarget();
- _fs->AddInstruction(_OP_DELEGATE, _fs->PushTarget(), table, delegate);
- }
- void DeleteExpr()
- {
- ExpState es;
- Lex(); PushExpState();
- _exst._class_or_delete = true;
- _exst._funcarg = false;
- PrefixedExpr();
- es = PopExpState();
- if(es._deref == DEREF_NO_DEREF) Error(_SC("can't delete an expression"));
- if(es._deref == DEREF_FIELD) Emit2ArgsOP(_OP_DELETE);
- else Error(_SC("cannot delete a local"));
- }
- void PrefixIncDec(SQInteger token)
- {
- ExpState es;
- Lex(); PushExpState();
- _exst._class_or_delete = true;
- _exst._funcarg = false;
- PrefixedExpr();
- es = PopExpState();
- if(es._deref == DEREF_FIELD) Emit2ArgsOP(_OP_INC,token == TK_MINUSMINUS?-1:1);
- else {
- SQInteger src = _fs->PopTarget();
- _fs->AddInstruction(_OP_INCL, _fs->PushTarget(), src, 0, token == TK_MINUSMINUS?-1:1);
- }
- }
- void CreateFunction(SQObject &name)
- {
-
- SQFuncState *funcstate = _fs->PushChildState(_ss(_vm));
- funcstate->_name = name;
- SQObject paramname;
- funcstate->AddParameter(_fs->CreateString(_SC("this")));
- funcstate->_sourcename = _sourcename;
- SQInteger defparams = 0;
- while(_token!=_SC(')')) {
- if(_token == TK_VARPARAMS) {
- if(defparams > 0) Error(_SC("function with default parameters cannot have variable number of parameters"));
- funcstate->_varparams = true;
- Lex();
- if(_token != _SC(')')) Error(_SC("expected ')'"));
- break;
- }
- else {
- paramname = Expect(TK_IDENTIFIER);
- funcstate->AddParameter(paramname);
- if(_token == _SC('=')) {
- Lex();
- Expression();
- funcstate->AddDefaultParam(_fs->TopTarget());
- defparams++;
- }
- else {
- if(defparams > 0) Error(_SC("expected '='"));
- }
- if(_token == _SC(',')) Lex();
- else if(_token != _SC(')')) Error(_SC("expected ')' or ','"));
- }
- }
- Expect(_SC(')'));
- for(SQInteger n = 0; n < defparams; n++) {
- _fs->PopTarget();
- }
- //outer values
- if(_token == _SC(':')) {
- Lex(); Expect(_SC('('));
- while(_token != _SC(')')) {
- paramname = Expect(TK_IDENTIFIER);
- //outers are treated as implicit local variables
- funcstate->AddOuterValue(paramname);
- if(_token == _SC(',')) Lex();
- else if(_token != _SC(')')) Error(_SC("expected ')' or ','"));
- }
- Lex();
- }
-
- SQFuncState *currchunk = _fs;
- _fs = funcstate;
- Statement();
- funcstate->AddLineInfos(_lex._prevtoken == _SC('\n')?_lex._lasttokenline:_lex._currentline, _lineinfo, true);
- funcstate->AddInstruction(_OP_RETURN, -1);
- funcstate->SetStackSize(0);
- //_fs->->_stacksize = _fs->_stacksize;
- SQFunctionProto *func = funcstate->BuildProto();
-#ifdef _DEBUG_DUMP
- funcstate->Dump(func);
-#endif
- _fs = currchunk;
- _fs->_functions.push_back(func);
- _fs->PopChildState();
- }
- void CleanStack(SQInteger stacksize)
- {
- if(_fs->GetStackSize() != stacksize)
- _fs->SetStackSize(stacksize);
- }
- void ResolveBreaks(SQFuncState *funcstate, SQInteger ntoresolve)
- {
- while(ntoresolve > 0) {
- SQInteger pos = funcstate->_unresolvedbreaks.back();
- funcstate->_unresolvedbreaks.pop_back();
- //set the jmp instruction
- funcstate->SetIntructionParams(pos, 0, funcstate->GetCurrentPos() - pos, 0);
- ntoresolve--;
- }
- }
- void ResolveContinues(SQFuncState *funcstate, SQInteger ntoresolve, SQInteger targetpos)
- {
- while(ntoresolve > 0) {
- SQInteger pos = funcstate->_unresolvedcontinues.back();
- funcstate->_unresolvedcontinues.pop_back();
- //set the jmp instruction
- funcstate->SetIntructionParams(pos, 0, targetpos - pos, 0);
- ntoresolve--;
- }
- }
-private:
- SQInteger _token;
- SQFuncState *_fs;
- SQObjectPtr _sourcename;
- SQLexer _lex;
- bool _lineinfo;
- bool _raiseerror;
- SQInteger _debugline;
- SQInteger _debugop;
- ExpStateVec _expstates;
- SQChar *compilererror;
- jmp_buf _errorjmp;
- SQVM *_vm;
-};
-
-bool Compile(SQVM *vm,SQLEXREADFUNC rg, SQUserPointer up, const SQChar *sourcename, SQObjectPtr &out, bool raiseerror, bool lineinfo)
-{
- SQCompiler p(vm, rg, up, sourcename, raiseerror, lineinfo);
- return p.Compile(out);
-}
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQCOMPILER_H_
-#define _SQCOMPILER_H_
-
-struct SQVM;
-
-#define TK_IDENTIFIER 258
-#define TK_STRING_LITERAL 259
-#define TK_INTEGER 260
-#define TK_FLOAT 261
-#define TK_DELEGATE 262
-#define TK_DELETE 263
-#define TK_EQ 264
-#define TK_NE 265
-#define TK_LE 266
-#define TK_GE 267
-#define TK_SWITCH 268
-#define TK_ARROW 269
-#define TK_AND 270
-#define TK_OR 271
-#define TK_IF 272
-#define TK_ELSE 273
-#define TK_WHILE 274
-#define TK_BREAK 275
-#define TK_FOR 276
-#define TK_DO 277
-#define TK_NULL 278
-#define TK_FOREACH 279
-#define TK_IN 280
-#define TK_NEWSLOT 281
-#define TK_MODULO 282
-#define TK_LOCAL 283
-#define TK_CLONE 284
-#define TK_FUNCTION 285
-#define TK_RETURN 286
-#define TK_TYPEOF 287
-#define TK_UMINUS 288
-#define TK_PLUSEQ 289
-#define TK_MINUSEQ 290
-#define TK_CONTINUE 291
-#define TK_YIELD 292
-#define TK_TRY 293
-#define TK_CATCH 294
-#define TK_THROW 295
-#define TK_SHIFTL 296
-#define TK_SHIFTR 297
-#define TK_RESUME 298
-#define TK_DOUBLE_COLON 299
-#define TK_CASE 300
-#define TK_DEFAULT 301
-#define TK_THIS 302
-#define TK_PLUSPLUS 303
-#define TK_MINUSMINUS 304
-#define TK_PARENT 305
-#define TK_USHIFTR 306
-#define TK_CLASS 307
-#define TK_EXTENDS 308
-#define TK_CONSTRUCTOR 310
-#define TK_INSTANCEOF 311
-#define TK_VARPARAMS 312
-#define TK_VARGC 313
-#define TK_VARGV 314
-#define TK_TRUE 315
-#define TK_FALSE 316
-#define TK_MULEQ 317
-#define TK_DIVEQ 318
-#define TK_MODEQ 319
-#define TK_ATTR_OPEN 320
-#define TK_ATTR_CLOSE 321
-#define TK_STATIC 322
-#define TK_ENUM 323
-#define TK_CONST 324
-
-
-typedef void(*CompilerErrorFunc)(void *ud, const SQChar *s);
-bool Compile(SQVM *vm, SQLEXREADFUNC rg, SQUserPointer up, const SQChar *sourcename, SQObjectPtr &out, bool raiseerror, bool lineinfo);
-#endif //_SQCOMPILER_H_
+++ /dev/null
-/*
- see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include <stdarg.h>
-#include "sqvm.h"
-#include "sqfuncproto.h"
-#include "sqclosure.h"
-#include "sqstring.h"
-
-SQRESULT sq_getfunctioninfo(HSQUIRRELVM v,SQInteger level,SQFunctionInfo *fi)
-{
- SQInteger cssize = v->_callsstacksize;
- if (cssize > level) {
- SQVM::CallInfo &ci = v->_callsstack[cssize-level-1];
- if(sq_isclosure(ci._closure)) {
- SQClosure *c = _closure(ci._closure);
- SQFunctionProto *proto = _funcproto(c->_function);
- fi->funcid = proto;
- fi->name = type(proto->_name) == OT_STRING?_stringval(proto->_name):_SC("unknown");
- fi->source = type(proto->_name) == OT_STRING?_stringval(proto->_sourcename):_SC("unknown");
- return SQ_OK;
- }
- }
- return sq_throwerror(v,_SC("the object is not a closure"));
-}
-
-SQRESULT sq_stackinfos(HSQUIRRELVM v, SQInteger level, SQStackInfos *si)
-{
- SQInteger cssize = v->_callsstacksize;
- if (cssize > level) {
- memset(si, 0, sizeof(SQStackInfos));
- SQVM::CallInfo &ci = v->_callsstack[cssize-level-1];
- switch (type(ci._closure)) {
- case OT_CLOSURE:{
- SQFunctionProto *func = _funcproto(_closure(ci._closure)->_function);
- if (type(func->_name) == OT_STRING)
- si->funcname = _stringval(func->_name);
- if (type(func->_sourcename) == OT_STRING)
- si->source = _stringval(func->_sourcename);
- si->line = func->GetLine(ci._ip);
- }
- break;
- case OT_NATIVECLOSURE:
- si->source = _SC("NATIVE");
- si->funcname = _SC("unknown");
- if(type(_nativeclosure(ci._closure)->_name) == OT_STRING)
- si->funcname = _stringval(_nativeclosure(ci._closure)->_name);
- si->line = -1;
- break;
- default: break; //shutup compiler
- }
- return SQ_OK;
- }
- return SQ_ERROR;
-}
-
-void SQVM::Raise_Error(const SQChar *s, ...)
-{
- va_list vl;
- va_start(vl, s);
- scvsprintf(_sp(rsl((SQInteger)scstrlen(s)+(NUMBER_MAX_CHAR*2))), s, vl);
- va_end(vl);
- _lasterror = SQString::Create(_ss(this),_spval,-1);
-}
-
-void SQVM::Raise_Error(SQObjectPtr &desc)
-{
- _lasterror = desc;
-}
-
-SQString *SQVM::PrintObjVal(const SQObject &o)
-{
- switch(type(o)) {
- case OT_STRING: return _string(o);
- case OT_INTEGER:
- scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)), _SC("%d"), _integer(o));
- return SQString::Create(_ss(this), _spval);
- break;
- case OT_FLOAT:
- scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)), _SC("%.14g"), _float(o));
- return SQString::Create(_ss(this), _spval);
- break;
- default:
- return SQString::Create(_ss(this), GetTypeName(o));
- }
-}
-
-void SQVM::Raise_IdxError(SQObject &o)
-{
- SQObjectPtr oval = PrintObjVal(o);
- Raise_Error(_SC("the index '%.50s' does not exist"), _stringval(oval));
-}
-
-void SQVM::Raise_CompareError(const SQObject &o1, const SQObject &o2)
-{
- SQObjectPtr oval1 = PrintObjVal(o1), oval2 = PrintObjVal(o2);
- Raise_Error(_SC("comparsion between '%.50s' and '%.50s'"), _stringval(oval1), _stringval(oval2));
-}
-
-
-void SQVM::Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type)
-{
- SQObjectPtr exptypes = SQString::Create(_ss(this), _SC(""), -1);
- SQInteger found = 0;
- for(SQInteger i=0; i<16; i++)
- {
- SQInteger mask = 0x00000001 << i;
- if(typemask & (mask)) {
- if(found>0) StringCat(exptypes,SQString::Create(_ss(this), _SC("|"), -1), exptypes);
- found ++;
- StringCat(exptypes,SQString::Create(_ss(this), IdType2Name((SQObjectType)mask), -1), exptypes);
- }
- }
- Raise_Error(_SC("parameter %d has an invalid type '%s' ; expected: '%s'"), nparam, IdType2Name((SQObjectType)type), _stringval(exptypes));
-}
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQFUNCTION_H_
-#define _SQFUNCTION_H_
-
-#include "sqopcodes.h"
-
-enum SQOuterType {
- otLOCAL = 0,
- otSYMBOL = 1,
- otOUTER = 2
-};
-
-struct SQOuterVar
-{
-
- SQOuterVar(){}
- SQOuterVar(const SQObjectPtr &name,const SQObjectPtr &src,SQOuterType t)
- {
- _name = name;
- _src=src;
- _type=t;
- }
- SQOuterVar(const SQOuterVar &ov)
- {
- _type=ov._type;
- _src=ov._src;
- _name=ov._name;
- }
- SQOuterType _type;
- SQObjectPtr _name;
- SQObjectPtr _src;
-};
-
-struct SQLocalVarInfo
-{
- SQLocalVarInfo():_start_op(0),_end_op(0){}
- SQLocalVarInfo(const SQLocalVarInfo &lvi)
- {
- _name=lvi._name;
- _start_op=lvi._start_op;
- _end_op=lvi._end_op;
- _pos=lvi._pos;
- }
- SQObjectPtr _name;
- SQUnsignedInteger _start_op;
- SQUnsignedInteger _end_op;
- SQUnsignedInteger _pos;
-};
-
-struct SQLineInfo { SQInteger _line;SQInteger _op; };
-
-typedef sqvector<SQOuterVar> SQOuterVarVec;
-typedef sqvector<SQLocalVarInfo> SQLocalVarInfoVec;
-typedef sqvector<SQLineInfo> SQLineInfoVec;
-
-#define _FUNC_SIZE(ni,nl,nparams,nfuncs,nouters,nlineinf,localinf,defparams) (sizeof(SQFunctionProto) \
- +((ni-1)*sizeof(SQInstruction))+(nl*sizeof(SQObjectPtr)) \
- +(nparams*sizeof(SQObjectPtr))+(nfuncs*sizeof(SQObjectPtr)) \
- +(nouters*sizeof(SQOuterVar))+(nlineinf*sizeof(SQLineInfo)) \
- +(localinf*sizeof(SQLocalVarInfo))+(defparams*sizeof(SQInteger)))
-
-#define _CONSTRUCT_VECTOR(type,size,ptr) { \
- for(SQInteger n = 0; n < size; n++) { \
- new (&ptr[n]) type(); \
- } \
-}
-
-#define _DESTRUCT_VECTOR(type,size,ptr) { \
- for(SQInteger nl = 0; nl < size; nl++) { \
- ptr[nl].~type(); \
- } \
-}
-struct SQFunctionProto : public SQRefCounted
-{
-private:
- SQFunctionProto(){
- _stacksize=0;
- _bgenerator=false;}
-public:
- static SQFunctionProto *Create(SQInteger ninstructions,
- SQInteger nliterals,SQInteger nparameters,
- SQInteger nfunctions,SQInteger noutervalues,
- SQInteger nlineinfos,SQInteger nlocalvarinfos,SQInteger ndefaultparams)
- {
- SQFunctionProto *f;
- //I compact the whole class and members in a single memory allocation
- f = (SQFunctionProto *)sq_vm_malloc(_FUNC_SIZE(ninstructions,nliterals,nparameters,nfunctions,noutervalues,nlineinfos,nlocalvarinfos,ndefaultparams));
- new (f) SQFunctionProto;
- f->_ninstructions = ninstructions;
- f->_literals = (SQObjectPtr*)&f->_instructions[ninstructions];
- f->_nliterals = nliterals;
- f->_parameters = (SQObjectPtr*)&f->_literals[nliterals];
- f->_nparameters = nparameters;
- f->_functions = (SQObjectPtr*)&f->_parameters[nparameters];
- f->_nfunctions = nfunctions;
- f->_outervalues = (SQOuterVar*)&f->_functions[nfunctions];
- f->_noutervalues = noutervalues;
- f->_lineinfos = (SQLineInfo *)&f->_outervalues[noutervalues];
- f->_nlineinfos = nlineinfos;
- f->_localvarinfos = (SQLocalVarInfo *)&f->_lineinfos[nlineinfos];
- f->_nlocalvarinfos = nlocalvarinfos;
- f->_defaultparams = (SQInteger *)&f->_localvarinfos[nlocalvarinfos];
- f->_ndefaultparams = ndefaultparams;
-
- _CONSTRUCT_VECTOR(SQObjectPtr,f->_nliterals,f->_literals);
- _CONSTRUCT_VECTOR(SQObjectPtr,f->_nparameters,f->_parameters);
- _CONSTRUCT_VECTOR(SQObjectPtr,f->_nfunctions,f->_functions);
- _CONSTRUCT_VECTOR(SQOuterVar,f->_noutervalues,f->_outervalues);
- //_CONSTRUCT_VECTOR(SQLineInfo,f->_nlineinfos,f->_lineinfos); //not required are 2 integers
- _CONSTRUCT_VECTOR(SQLocalVarInfo,f->_nlocalvarinfos,f->_localvarinfos);
- return f;
- }
- void Release(){
- _DESTRUCT_VECTOR(SQObjectPtr,_nliterals,_literals);
- _DESTRUCT_VECTOR(SQObjectPtr,_nparameters,_parameters);
- _DESTRUCT_VECTOR(SQObjectPtr,_nfunctions,_functions);
- _DESTRUCT_VECTOR(SQOuterVar,_noutervalues,_outervalues);
- //_DESTRUCT_VECTOR(SQLineInfo,_nlineinfos,_lineinfos); //not required are 2 integers
- _DESTRUCT_VECTOR(SQLocalVarInfo,_nlocalvarinfos,_localvarinfos);
- SQInteger size = _FUNC_SIZE(_ninstructions,_nliterals,_nparameters,_nfunctions,_noutervalues,_nlineinfos,_nlocalvarinfos,_ndefaultparams);
- this->~SQFunctionProto();
- sq_vm_free(this,size);
- }
- const SQChar* GetLocal(SQVM *v,SQUnsignedInteger stackbase,SQUnsignedInteger nseq,SQUnsignedInteger nop);
- SQInteger GetLine(SQInstruction *curr);
- bool Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write);
- static bool Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret);
-
- SQObjectPtr _sourcename;
- SQObjectPtr _name;
- SQInteger _stacksize;
- bool _bgenerator;
- bool _varparams;
-
- SQInteger _nlocalvarinfos;
- SQLocalVarInfo *_localvarinfos;
-
- SQInteger _nlineinfos;
- SQLineInfo *_lineinfos;
-
- SQInteger _nliterals;
- SQObjectPtr *_literals;
-
- SQInteger _nparameters;
- SQObjectPtr *_parameters;
-
- SQInteger _nfunctions;
- SQObjectPtr *_functions;
-
- SQInteger _noutervalues;
- SQOuterVar *_outervalues;
-
- SQInteger _ndefaultparams;
- SQInteger *_defaultparams;
-
- SQInteger _ninstructions;
- SQInstruction _instructions[1];
-};
-
-#endif //_SQFUNCTION_H_
+++ /dev/null
-/*
- see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include "sqcompiler.h"
-#include "sqfuncproto.h"
-#include "sqstring.h"
-#include "sqtable.h"
-#include "sqopcodes.h"
-#include "sqfuncstate.h"
-
-#ifdef _DEBUG_DUMP
-SQInstructionDesc g_InstrDesc[]={
- {_SC("_OP_LINE")},
- {_SC("_OP_LOAD")},
- {_SC("_OP_LOADINT")},
- {_SC("_OP_LOADFLOAT")},
- {_SC("_OP_DLOAD")},
- {_SC("_OP_TAILCALL")},
- {_SC("_OP_CALL")},
- {_SC("_OP_PREPCALL")},
- {_SC("_OP_PREPCALLK")},
- {_SC("_OP_GETK")},
- {_SC("_OP_MOVE")},
- {_SC("_OP_NEWSLOT")},
- {_SC("_OP_DELETE")},
- {_SC("_OP_SET")},
- {_SC("_OP_GET")},
- {_SC("_OP_EQ")},
- {_SC("_OP_NE")},
- {_SC("_OP_ARITH")},
- {_SC("_OP_BITW")},
- {_SC("_OP_RETURN")},
- {_SC("_OP_LOADNULLS")},
- {_SC("_OP_LOADROOTTABLE")},
- {_SC("_OP_LOADBOOL")},
- {_SC("_OP_DMOVE")},
- {_SC("_OP_JMP")},
- {_SC("_OP_JNZ")},
- {_SC("_OP_JZ")},
- {_SC("_OP_LOADFREEVAR")},
- {_SC("_OP_VARGC")},
- {_SC("_OP_GETVARGV")},
- {_SC("_OP_NEWTABLE")},
- {_SC("_OP_NEWARRAY")},
- {_SC("_OP_APPENDARRAY")},
- {_SC("_OP_GETPARENT")},
- {_SC("_OP_COMPARITH")},
- {_SC("_OP_COMPARITHL")},
- {_SC("_OP_INC")},
- {_SC("_OP_INCL")},
- {_SC("_OP_PINC")},
- {_SC("_OP_PINCL")},
- {_SC("_OP_CMP")},
- {_SC("_OP_EXISTS")},
- {_SC("_OP_INSTANCEOF")},
- {_SC("_OP_AND")},
- {_SC("_OP_OR")},
- {_SC("_OP_NEG")},
- {_SC("_OP_NOT")},
- {_SC("_OP_BWNOT")},
- {_SC("_OP_CLOSURE")},
- {_SC("_OP_YIELD")},
- {_SC("_OP_RESUME")},
- {_SC("_OP_FOREACH")},
- {_SC("_OP_POSTFOREACH")},
- {_SC("_OP_DELEGATE")},
- {_SC("_OP_CLONE")},
- {_SC("_OP_TYPEOF")},
- {_SC("_OP_PUSHTRAP")},
- {_SC("_OP_POPTRAP")},
- {_SC("_OP_THROW")},
- {_SC("_OP_CLASS")},
- {_SC("_OP_NEWSLOTA")}
-};
-#endif
-void DumpLiteral(SQObjectPtr &o)
-{
- switch(type(o)){
- case OT_STRING: scprintf(_SC("\"%s\""),_stringval(o));break;
- case OT_FLOAT: scprintf(_SC("{%f}"),_float(o));break;
- case OT_INTEGER: scprintf(_SC("{%d}"),_integer(o));break;
- case OT_BOOL: scprintf(_SC("%s"),_integer(o)?_SC("true"):_SC("false"));break;
- default: scprintf(_SC("(%s %p)"),GetTypeName(o),_rawval(o));break; break; //shut up compiler
- }
-}
-
-SQFuncState::SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc efunc,void *ed)
-{
- _nliterals = 0;
- _literals = SQTable::Create(ss,0);
- _strings = SQTable::Create(ss,0);
- _sharedstate = ss;
- _lastline = 0;
- _optimization = true;
- _parent = parent;
- _stacksize = 0;
- _traps = 0;
- _returnexp = 0;
- _varparams = false;
- _errfunc = efunc;
- _errtarget = ed;
- _bgenerator = false;
-
-}
-
-void SQFuncState::Error(const SQChar *err)
-{
- _errfunc(_errtarget,err);
-}
-
-#ifdef _DEBUG_DUMP
-void SQFuncState::Dump(SQFunctionProto *func)
-{
- SQUnsignedInteger n=0,i;
- SQInteger si;
- scprintf(_SC("SQInstruction sizeof %d\n"),sizeof(SQInstruction));
- scprintf(_SC("SQObject sizeof %d\n"),sizeof(SQObject));
- scprintf(_SC("--------------------------------------------------------------------\n"));
- scprintf(_SC("*****FUNCTION [%s]\n"),type(func->_name)==OT_STRING?_stringval(func->_name):_SC("unknown"));
- scprintf(_SC("-----LITERALS\n"));
- SQObjectPtr refidx,key,val;
- SQInteger idx;
- SQObjectPtrVec templiterals;
- templiterals.resize(_nliterals);
- while((idx=_table(_literals)->Next(false,refidx,key,val))!=-1) {
- refidx=idx;
- templiterals[_integer(val)]=key;
- }
- for(i=0;i<templiterals.size();i++){
- scprintf(_SC("[%d] "),n);
- DumpLiteral(templiterals[i]);
- scprintf(_SC("\n"));
- n++;
- }
- scprintf(_SC("-----PARAMS\n"));
- if(_varparams)
- scprintf(_SC("<<VARPARAMS>>\n"));
- n=0;
- for(i=0;i<_parameters.size();i++){
- scprintf(_SC("[%d] "),n);
- DumpLiteral(_parameters[i]);
- scprintf(_SC("\n"));
- n++;
- }
- scprintf(_SC("-----LOCALS\n"));
- for(si=0;si<func->_nlocalvarinfos;si++){
- SQLocalVarInfo lvi=func->_localvarinfos[si];
- scprintf(_SC("[%d] %s \t%d %d\n"),lvi._pos,_stringval(lvi._name),lvi._start_op,lvi._end_op);
- n++;
- }
- scprintf(_SC("-----LINE INFO\n"));
- for(i=0;i<_lineinfos.size();i++){
- SQLineInfo li=_lineinfos[i];
- scprintf(_SC("op [%d] line [%d] \n"),li._op,li._line);
- n++;
- }
- scprintf(_SC("-----dump\n"));
- n=0;
- for(i=0;i<_instructions.size();i++){
- SQInstruction &inst=_instructions[i];
- if(inst.op==_OP_LOAD || inst.op==_OP_DLOAD || inst.op==_OP_PREPCALLK || inst.op==_OP_GETK ){
-
- SQInteger lidx = inst._arg1;
- scprintf(_SC("[%03d] %15s %d "),n,g_InstrDesc[inst.op].name,inst._arg0);
- if(lidx >= 0xFFFFFFFF)
- scprintf(_SC("null"));
- else {
- SQInteger refidx;
- SQObjectPtr val,key,refo;
- while(((refidx=_table(_literals)->Next(false,refo,key,val))!= -1) && (_integer(val) != lidx)) {
- refo = refidx;
- }
- DumpLiteral(key);
- }
- if(inst.op != _OP_DLOAD) {
- scprintf(_SC(" %d %d \n"),inst._arg2,inst._arg3);
- }
- else {
- scprintf(_SC(" %d "),inst._arg2);
- lidx = inst._arg3;
- if(lidx >= 0xFFFFFFFF)
- scprintf(_SC("null"));
- else {
- SQInteger refidx;
- SQObjectPtr val,key,refo;
- while(((refidx=_table(_literals)->Next(false,refo,key,val))!= -1) && (_integer(val) != lidx)) {
- refo = refidx;
- }
- DumpLiteral(key);
- scprintf(_SC("\n"));
- }
- }
- }
- else if(inst.op==_OP_LOADFLOAT) {
- scprintf(_SC("[%03d] %15s %d %f %d %d\n"),n,g_InstrDesc[inst.op].name,inst._arg0,*((SQFloat*)&inst._arg1),inst._arg2,inst._arg3);
- }
- else if(inst.op==_OP_ARITH){
- scprintf(_SC("[%03d] %15s %d %d %d %c\n"),n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3);
- }
- else
- scprintf(_SC("[%03d] %15s %d %d %d %d\n"),n,g_InstrDesc[inst.op].name,inst._arg0,inst._arg1,inst._arg2,inst._arg3);
- n++;
- }
- scprintf(_SC("-----\n"));
- scprintf(_SC("stack size[%d]\n"),func->_stacksize);
- scprintf(_SC("--------------------------------------------------------------------\n\n"));
-}
-#endif
-
-SQInteger SQFuncState::GetNumericConstant(const SQInteger cons)
-{
- return GetConstant(SQObjectPtr(cons));
-}
-
-SQInteger SQFuncState::GetNumericConstant(const SQFloat cons)
-{
- return GetConstant(SQObjectPtr(cons));
-}
-
-SQInteger SQFuncState::GetConstant(const SQObject &cons)
-{
- SQObjectPtr val;
- if(!_table(_literals)->Get(cons,val))
- {
- val = _nliterals;
- _table(_literals)->NewSlot(cons,val);
- _nliterals++;
- if(_nliterals > MAX_LITERALS) {
- val.Null();
- Error(_SC("internal compiler error: too many literals"));
- }
- }
- return _integer(val);
-}
-
-void SQFuncState::SetIntructionParams(SQInteger pos,SQInteger arg0,SQInteger arg1,SQInteger arg2,SQInteger arg3)
-{
- _instructions[pos]._arg0=(unsigned char)*((SQUnsignedInteger *)&arg0);
- _instructions[pos]._arg1=(SQInt32)*((SQUnsignedInteger *)&arg1);
- _instructions[pos]._arg2=(unsigned char)*((SQUnsignedInteger *)&arg2);
- _instructions[pos]._arg3=(unsigned char)*((SQUnsignedInteger *)&arg3);
-}
-
-void SQFuncState::SetIntructionParam(SQInteger pos,SQInteger arg,SQInteger val)
-{
- switch(arg){
- case 0:_instructions[pos]._arg0=(unsigned char)*((SQUnsignedInteger *)&val);break;
- case 1:case 4:_instructions[pos]._arg1=(SQInt32)*((SQUnsignedInteger *)&val);break;
- case 2:_instructions[pos]._arg2=(unsigned char)*((SQUnsignedInteger *)&val);break;
- case 3:_instructions[pos]._arg3=(unsigned char)*((SQUnsignedInteger *)&val);break;
- };
-}
-
-SQInteger SQFuncState::AllocStackPos()
-{
- SQInteger npos=_vlocals.size();
- _vlocals.push_back(SQLocalVarInfo());
- if(_vlocals.size()>((SQUnsignedInteger)_stacksize)) {
- if(_stacksize>MAX_FUNC_STACKSIZE) Error(_SC("internal compiler error: too many locals"));
- _stacksize=_vlocals.size();
- }
- return npos;
-}
-
-SQInteger SQFuncState::PushTarget(SQInteger n)
-{
- if(n!=-1){
- _targetstack.push_back(n);
- return n;
- }
- n=AllocStackPos();
- _targetstack.push_back(n);
- return n;
-}
-
-SQInteger SQFuncState::GetUpTarget(SQInteger n){
- return _targetstack[((_targetstack.size()-1)-n)];
-}
-
-SQInteger SQFuncState::TopTarget(){
- return _targetstack.back();
-}
-SQInteger SQFuncState::PopTarget()
-{
- SQInteger npos=_targetstack.back();
- SQLocalVarInfo t=_vlocals[_targetstack.back()];
- if(type(t._name)==OT_NULL){
- _vlocals.pop_back();
- }
- _targetstack.pop_back();
- return npos;
-}
-
-SQInteger SQFuncState::GetStackSize()
-{
- return _vlocals.size();
-}
-
-void SQFuncState::SetStackSize(SQInteger n)
-{
- SQInteger size=_vlocals.size();
- while(size>n){
- size--;
- SQLocalVarInfo lvi=_vlocals.back();
- if(type(lvi._name)!=OT_NULL){
- lvi._end_op=GetCurrentPos();
- _localvarinfos.push_back(lvi);
- }
- _vlocals.pop_back();
- }
-}
-
-bool SQFuncState::IsConstant(const SQObject &name,SQObject &e)
-{
- SQObjectPtr val;
- if(_table(_sharedstate->_consts)->Get(name,val)) {
- e = val;
- return true;
- }
- return false;
-}
-
-bool SQFuncState::IsLocal(SQUnsignedInteger stkpos)
-{
- if(stkpos>=_vlocals.size())return false;
- else if(type(_vlocals[stkpos]._name)!=OT_NULL)return true;
- return false;
-}
-
-SQInteger SQFuncState::PushLocalVariable(const SQObject &name)
-{
- SQInteger pos=_vlocals.size();
- SQLocalVarInfo lvi;
- lvi._name=name;
- lvi._start_op=GetCurrentPos()+1;
- lvi._pos=_vlocals.size();
- _vlocals.push_back(lvi);
- if(_vlocals.size()>((SQUnsignedInteger)_stacksize))_stacksize=_vlocals.size();
-
- return pos;
-}
-
-SQInteger SQFuncState::GetLocalVariable(const SQObject &name)
-{
- SQInteger locals=_vlocals.size();
- while(locals>=1){
- if(type(_vlocals[locals-1]._name)==OT_STRING && _string(_vlocals[locals-1]._name)==_string(name)){
- return locals-1;
- }
- locals--;
- }
- return -1;
-}
-
-SQInteger SQFuncState::GetOuterVariable(const SQObject &name)
-{
- SQInteger outers = _outervalues.size();
- for(SQInteger i = 0; i<outers; i++) {
- if(_string(_outervalues[i]._name) == _string(name))
- return i;
- }
- return -1;
-}
-
-void SQFuncState::AddOuterValue(const SQObject &name)
-{
- SQInteger pos=-1;
- if(_parent) {
- pos = _parent->GetLocalVariable(name);
- if(pos == -1) {
- pos = _parent->GetOuterVariable(name);
- if(pos != -1) {
- _outervalues.push_back(SQOuterVar(name,SQObjectPtr(SQInteger(pos)),otOUTER)); //local
- return;
- }
- }
- else {
- _outervalues.push_back(SQOuterVar(name,SQObjectPtr(SQInteger(pos)),otLOCAL)); //local
- return;
- }
- }
- _outervalues.push_back(SQOuterVar(name,name,otSYMBOL)); //global
-}
-
-void SQFuncState::AddParameter(const SQObject &name)
-{
- PushLocalVariable(name);
- _parameters.push_back(name);
-}
-
-void SQFuncState::AddLineInfos(SQInteger line,bool lineop,bool force)
-{
- if(_lastline!=line || force){
- SQLineInfo li;
- li._line=line;li._op=(GetCurrentPos()+1);
- if(lineop)AddInstruction(_OP_LINE,0,line);
- _lineinfos.push_back(li);
- _lastline=line;
- }
-}
-
-void SQFuncState::AddInstruction(SQInstruction &i)
-{
- SQInteger size = _instructions.size();
- if(size > 0 && _optimization){ //simple optimizer
- SQInstruction &pi = _instructions[size-1];//previous instruction
- switch(i.op) {
- case _OP_RETURN:
- if( _parent && i._arg0 != MAX_FUNC_STACKSIZE && pi.op == _OP_CALL && _returnexp < size-1) {
- pi.op = _OP_TAILCALL;
- }
- break;
- case _OP_GET:
- if( pi.op == _OP_LOAD && pi._arg0 == i._arg2 && (!IsLocal(pi._arg0))){
- pi._arg1 = pi._arg1;
- pi._arg2 = (unsigned char)i._arg1;
- pi.op = _OP_GETK;
- pi._arg0 = i._arg0;
-
- return;
- }
- break;
- case _OP_PREPCALL:
- if( pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0))){
- pi.op = _OP_PREPCALLK;
- pi._arg0 = i._arg0;
- pi._arg1 = pi._arg1;
- pi._arg2 = i._arg2;
- pi._arg3 = i._arg3;
- return;
- }
- break;
- case _OP_APPENDARRAY:
- if(pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0))){
- pi.op = _OP_APPENDARRAY;
- pi._arg0 = i._arg0;
- pi._arg1 = pi._arg1;
- pi._arg2 = MAX_FUNC_STACKSIZE;
- pi._arg3 = MAX_FUNC_STACKSIZE;
- return;
- }
- break;
- case _OP_MOVE:
- if((pi.op == _OP_GET || pi.op == _OP_ARITH || pi.op == _OP_BITW) && (pi._arg0 == i._arg1))
- {
- pi._arg0 = i._arg0;
- _optimization = false;
- return;
- }
-
- if(pi.op == _OP_MOVE)
- {
- pi.op = _OP_DMOVE;
- pi._arg2 = i._arg0;
- pi._arg3 = (unsigned char)i._arg1;
- return;
- }
- break;
- case _OP_LOAD:
- if(pi.op == _OP_LOAD && i._arg1 < 256) {
- pi.op = _OP_DLOAD;
- pi._arg2 = i._arg0;
- pi._arg3 = (unsigned char)i._arg1;
- return;
- }
- break;
- case _OP_EQ:case _OP_NE:
- if(pi.op == _OP_LOAD && pi._arg0 == i._arg1 && (!IsLocal(pi._arg0) ))
- {
- pi.op = i.op;
- pi._arg0 = i._arg0;
- pi._arg1 = pi._arg1;
- pi._arg2 = i._arg2;
- pi._arg3 = MAX_FUNC_STACKSIZE;
- return;
- }
- break;
- case _OP_LOADNULLS:
- if((pi.op == _OP_LOADNULLS && pi._arg0+pi._arg1 == i._arg0)) {
-
- pi._arg1 = pi._arg1 + 1;
- pi.op = _OP_LOADNULLS;
- return;
- }
- break;
- case _OP_LINE:
- if(pi.op == _OP_LINE) {
- _instructions.pop_back();
- _lineinfos.pop_back();
- }
- break;
- }
- }
- _optimization = true;
- _instructions.push_back(i);
-}
-
-SQObject SQFuncState::CreateString(const SQChar *s,SQInteger len)
-{
- SQObjectPtr ns(SQString::Create(_sharedstate,s,len));
- _table(_strings)->NewSlot(ns,(SQInteger)1);
- return ns;
-}
-
-SQObject SQFuncState::CreateTable()
-{
- SQObjectPtr nt(SQTable::Create(_sharedstate,0));
- _table(_strings)->NewSlot(nt,(SQInteger)1);
- return nt;
-}
-
-SQFunctionProto *SQFuncState::BuildProto()
-{
- SQFunctionProto *f=SQFunctionProto::Create(_instructions.size(),
- _nliterals,_parameters.size(),_functions.size(),_outervalues.size(),
- _lineinfos.size(),_localvarinfos.size(),_defaultparams.size());
-
- SQObjectPtr refidx,key,val;
- SQInteger idx;
-
- f->_stacksize = _stacksize;
- f->_sourcename = _sourcename;
- f->_bgenerator = _bgenerator;
- f->_name = _name;
-
- while((idx=_table(_literals)->Next(false,refidx,key,val))!=-1) {
- f->_literals[_integer(val)]=key;
- refidx=idx;
- }
-
- for(SQUnsignedInteger nf = 0; nf < _functions.size(); nf++) f->_functions[nf] = _functions[nf];
- for(SQUnsignedInteger np = 0; np < _parameters.size(); np++) f->_parameters[np] = _parameters[np];
- for(SQUnsignedInteger no = 0; no < _outervalues.size(); no++) f->_outervalues[no] = _outervalues[no];
- for(SQUnsignedInteger no = 0; no < _localvarinfos.size(); no++) f->_localvarinfos[no] = _localvarinfos[no];
- for(SQUnsignedInteger no = 0; no < _lineinfos.size(); no++) f->_lineinfos[no] = _lineinfos[no];
- for(SQUnsignedInteger no = 0; no < _defaultparams.size(); no++) f->_defaultparams[no] = _defaultparams[no];
-
- memcpy(f->_instructions,&_instructions[0],_instructions.size()*sizeof(SQInstruction));
-
- f->_varparams = _varparams;
-
- return f;
-}
-
-SQFuncState *SQFuncState::PushChildState(SQSharedState *ss)
-{
- SQFuncState *child = (SQFuncState *)sq_malloc(sizeof(SQFuncState));
- new (child) SQFuncState(ss,this,_errfunc,_errtarget);
- _childstates.push_back(child);
- return child;
-}
-
-void SQFuncState::PopChildState()
-{
- SQFuncState *child = _childstates.back();
- sq_delete(child,SQFuncState);
- _childstates.pop_back();
-}
-
-SQFuncState::~SQFuncState()
-{
- while(_childstates.size() > 0)
- {
- PopChildState();
- }
-}
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQFUNCSTATE_H_
-#define _SQFUNCSTATE_H_
-///////////////////////////////////
-#include "squtils.h"
-
-struct SQFuncState
-{
- SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc efunc,void *ed);
- ~SQFuncState();
-#ifdef _DEBUG_DUMP
- void Dump(SQFunctionProto *func);
-#endif
- void Error(const SQChar *err);
- SQFuncState *PushChildState(SQSharedState *ss);
- void PopChildState();
- void AddInstruction(SQOpcode _op,SQInteger arg0=0,SQInteger arg1=0,SQInteger arg2=0,SQInteger arg3=0){SQInstruction i(_op,arg0,arg1,arg2,arg3);AddInstruction(i);}
- void AddInstruction(SQInstruction &i);
- void SetIntructionParams(SQInteger pos,SQInteger arg0,SQInteger arg1,SQInteger arg2=0,SQInteger arg3=0);
- void SetIntructionParam(SQInteger pos,SQInteger arg,SQInteger val);
- SQInstruction &GetInstruction(SQInteger pos){return _instructions[pos];}
- void PopInstructions(SQInteger size){for(SQInteger i=0;i<size;i++)_instructions.pop_back();}
- void SetStackSize(SQInteger n);
- void SnoozeOpt(){_optimization=false;}
- void AddDefaultParam(SQInteger trg) { _defaultparams.push_back(trg); }
- SQInteger GetDefaultParamCount() { return _defaultparams.size(); }
- SQInteger GetCurrentPos(){return _instructions.size()-1;}
- SQInteger GetNumericConstant(const SQInteger cons);
- SQInteger GetNumericConstant(const SQFloat cons);
- SQInteger PushLocalVariable(const SQObject &name);
- void AddParameter(const SQObject &name);
- void AddOuterValue(const SQObject &name);
- SQInteger GetLocalVariable(const SQObject &name);
- SQInteger GetOuterVariable(const SQObject &name);
- SQInteger GenerateCode();
- SQInteger GetStackSize();
- SQInteger CalcStackFrameSize();
- void AddLineInfos(SQInteger line,bool lineop,bool force=false);
- SQFunctionProto *BuildProto();
- SQInteger AllocStackPos();
- SQInteger PushTarget(SQInteger n=-1);
- SQInteger PopTarget();
- SQInteger TopTarget();
- SQInteger GetUpTarget(SQInteger n);
- bool IsLocal(SQUnsignedInteger stkpos);
- SQObject CreateString(const SQChar *s,SQInteger len = -1);
- SQObject CreateTable();
- bool IsConstant(const SQObject &name,SQObject &e);
- SQInteger _returnexp;
- SQLocalVarInfoVec _vlocals;
- SQIntVec _targetstack;
- SQInteger _stacksize;
- bool _varparams;
- bool _bgenerator;
- SQIntVec _unresolvedbreaks;
- SQIntVec _unresolvedcontinues;
- SQObjectPtrVec _functions;
- SQObjectPtrVec _parameters;
- SQOuterVarVec _outervalues;
- SQInstructionVec _instructions;
- SQLocalVarInfoVec _localvarinfos;
- SQObjectPtr _literals;
- SQObjectPtr _strings;
- SQObjectPtr _name;
- SQObjectPtr _sourcename;
- SQInteger _nliterals;
- SQLineInfoVec _lineinfos;
- SQFuncState *_parent;
- SQIntVec _breaktargets;
- SQIntVec _continuetargets;
- SQIntVec _defaultparams;
- SQInteger _lastline;
- SQInteger _traps; //contains number of nested exception traps
- bool _optimization;
- SQSharedState *_sharedstate;
- sqvector<SQFuncState*> _childstates;
- SQInteger GetConstant(const SQObject &cons);
-private:
- CompilerErrorFunc _errfunc;
- void *_errtarget;
-};
-
-
-#endif //_SQFUNCSTATE_H_
-
+++ /dev/null
-/*
- see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include <ctype.h>
-#include <stdlib.h>
-#include "sqtable.h"
-#include "sqstring.h"
-#include "sqcompiler.h"
-#include "sqlexer.h"
-
-#define CUR_CHAR (_currdata)
-#define RETURN_TOKEN(t) { _prevtoken = _curtoken; _curtoken = t; return t;}
-#define IS_EOB() (CUR_CHAR <= SQUIRREL_EOB)
-#define NEXT() {Next();_currentcolumn++;}
-#define INIT_TEMP_STRING() { _longstr.resize(0);}
-#define APPEND_CHAR(c) { _longstr.push_back(c);}
-#define TERMINATE_BUFFER() {_longstr.push_back(_SC('\0'));}
-#define ADD_KEYWORD(key,id) _keywords->NewSlot( SQString::Create(ss, _SC(#key)) ,SQInteger(id))
-
-SQLexer::SQLexer(){}
-SQLexer::~SQLexer()
-{
- _keywords->Release();
-}
-
-void SQLexer::Init(SQSharedState *ss, SQLEXREADFUNC rg, SQUserPointer up,CompilerErrorFunc efunc,void *ed)
-{
- _errfunc = efunc;
- _errtarget = ed;
- _sharedstate = ss;
- _keywords = SQTable::Create(ss, 26);
- ADD_KEYWORD(while, TK_WHILE);
- ADD_KEYWORD(do, TK_DO);
- ADD_KEYWORD(if, TK_IF);
- ADD_KEYWORD(else, TK_ELSE);
- ADD_KEYWORD(break, TK_BREAK);
- ADD_KEYWORD(continue, TK_CONTINUE);
- ADD_KEYWORD(return, TK_RETURN);
- ADD_KEYWORD(null, TK_NULL);
- ADD_KEYWORD(function, TK_FUNCTION);
- ADD_KEYWORD(local, TK_LOCAL);
- ADD_KEYWORD(for, TK_FOR);
- ADD_KEYWORD(foreach, TK_FOREACH);
- ADD_KEYWORD(in, TK_IN);
- ADD_KEYWORD(typeof, TK_TYPEOF);
- ADD_KEYWORD(delegate, TK_DELEGATE);
- ADD_KEYWORD(delete, TK_DELETE);
- ADD_KEYWORD(try, TK_TRY);
- ADD_KEYWORD(catch, TK_CATCH);
- ADD_KEYWORD(throw, TK_THROW);
- ADD_KEYWORD(clone, TK_CLONE);
- ADD_KEYWORD(yield, TK_YIELD);
- ADD_KEYWORD(resume, TK_RESUME);
- ADD_KEYWORD(switch, TK_SWITCH);
- ADD_KEYWORD(case, TK_CASE);
- ADD_KEYWORD(default, TK_DEFAULT);
- ADD_KEYWORD(this, TK_THIS);
- ADD_KEYWORD(parent,TK_PARENT);
- ADD_KEYWORD(class,TK_CLASS);
- ADD_KEYWORD(extends,TK_EXTENDS);
- ADD_KEYWORD(constructor,TK_CONSTRUCTOR);
- ADD_KEYWORD(instanceof,TK_INSTANCEOF);
- ADD_KEYWORD(vargc,TK_VARGC);
- ADD_KEYWORD(vargv,TK_VARGV);
- ADD_KEYWORD(true,TK_TRUE);
- ADD_KEYWORD(false,TK_FALSE);
- ADD_KEYWORD(static,TK_STATIC);
- ADD_KEYWORD(enum,TK_ENUM);
- ADD_KEYWORD(const,TK_CONST);
-
- _readf = rg;
- _up = up;
- _lasttokenline = _currentline = 1;
- _currentcolumn = 0;
- _prevtoken = -1;
- Next();
-}
-
-void SQLexer::Error(const SQChar *err)
-{
- _errfunc(_errtarget,err);
-}
-
-void SQLexer::Next()
-{
- SQInteger t = _readf(_up);
- if(t > MAX_CHAR) Error(_SC("Invalid character"));
- if(t != 0) {
- _currdata = (LexChar)t;
- return;
- }
- _currdata = SQUIRREL_EOB;
-}
-
-const SQChar *SQLexer::Tok2Str(SQInteger tok)
-{
- SQObjectPtr itr, key, val;
- SQInteger nitr;
- while((nitr = _keywords->Next(false,itr, key, val)) != -1) {
- itr = (SQInteger)nitr;
- if(((SQInteger)_integer(val)) == tok)
- return _stringval(key);
- }
- return NULL;
-}
-
-void SQLexer::LexBlockComment()
-{
- bool done = false;
- while(!done) {
- switch(CUR_CHAR) {
- case _SC('*'): { NEXT(); if(CUR_CHAR == _SC('/')) { done = true; NEXT(); }}; continue;
- case _SC('\n'): _currentline++; NEXT(); continue;
- case SQUIRREL_EOB: Error(_SC("missing \"*/\" in comment"));
- default: NEXT();
- }
- }
-}
-
-SQInteger SQLexer::Lex()
-{
- _lasttokenline = _currentline;
- while(CUR_CHAR != SQUIRREL_EOB) {
- switch(CUR_CHAR){
- case _SC('\t'): case _SC('\r'): case _SC(' '): NEXT(); continue;
- case _SC('\n'):
- _currentline++;
- _prevtoken=_curtoken;
- _curtoken=_SC('\n');
- NEXT();
- _currentcolumn=1;
- continue;
- case _SC('/'):
- NEXT();
- switch(CUR_CHAR){
- case _SC('*'):
- NEXT();
- LexBlockComment();
- continue;
- case _SC('/'):
- do { NEXT(); } while (CUR_CHAR != _SC('\n') && (!IS_EOB()));
- continue;
- case _SC('='):
- NEXT();
- RETURN_TOKEN(TK_DIVEQ);
- continue;
- case _SC('>'):
- NEXT();
- RETURN_TOKEN(TK_ATTR_CLOSE);
- continue;
- default:
- RETURN_TOKEN('/');
- }
- case _SC('='):
- NEXT();
- if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('=') }
- else { NEXT(); RETURN_TOKEN(TK_EQ); }
- case _SC('<'):
- NEXT();
- if ( CUR_CHAR == _SC('=') ) { NEXT(); RETURN_TOKEN(TK_LE) }
- else if ( CUR_CHAR == _SC('-') ) { NEXT(); RETURN_TOKEN(TK_NEWSLOT); }
- else if ( CUR_CHAR == _SC('<') ) { NEXT(); RETURN_TOKEN(TK_SHIFTL); }
- else if ( CUR_CHAR == _SC('/') ) { NEXT(); RETURN_TOKEN(TK_ATTR_OPEN); }
- //else if ( CUR_CHAR == _SC('[') ) { NEXT(); ReadMultilineString(); RETURN_TOKEN(TK_STRING_LITERAL); }
- else { RETURN_TOKEN('<') }
- case _SC('>'):
- NEXT();
- if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_GE);}
- else if(CUR_CHAR == _SC('>')){
- NEXT();
- if(CUR_CHAR == _SC('>')){
- NEXT();
- RETURN_TOKEN(TK_USHIFTR);
- }
- RETURN_TOKEN(TK_SHIFTR);
- }
- else { RETURN_TOKEN('>') }
- case _SC('!'):
- NEXT();
- if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('!')}
- else { NEXT(); RETURN_TOKEN(TK_NE); }
- case _SC('@'): {
- SQInteger stype;
- NEXT();
- if(CUR_CHAR != _SC('"'))
- Error(_SC("string expected"));
- if((stype=ReadString('"',true))!=-1) {
- RETURN_TOKEN(stype);
- }
- Error(_SC("error parsing the string"));
- }
- case _SC('"'):
- case _SC('\''): {
- SQInteger stype;
- if((stype=ReadString(CUR_CHAR,false))!=-1){
- RETURN_TOKEN(stype);
- }
- Error(_SC("error parsing the string"));
- }
- case _SC('{'): case _SC('}'): case _SC('('): case _SC(')'): case _SC('['): case _SC(']'):
- case _SC(';'): case _SC(','): case _SC('?'): case _SC('^'): case _SC('~'):
- {SQInteger ret = CUR_CHAR;
- NEXT(); RETURN_TOKEN(ret); }
- case _SC('.'):
- NEXT();
- if (CUR_CHAR != _SC('.')){ RETURN_TOKEN('.') }
- NEXT();
- if (CUR_CHAR != _SC('.')){ Error(_SC("invalid token '..'")); }
- NEXT();
- RETURN_TOKEN(TK_VARPARAMS);
- case _SC('&'):
- NEXT();
- if (CUR_CHAR != _SC('&')){ RETURN_TOKEN('&') }
- else { NEXT(); RETURN_TOKEN(TK_AND); }
- case _SC('|'):
- NEXT();
- if (CUR_CHAR != _SC('|')){ RETURN_TOKEN('|') }
- else { NEXT(); RETURN_TOKEN(TK_OR); }
- case _SC(':'):
- NEXT();
- if (CUR_CHAR != _SC(':')){ RETURN_TOKEN(':') }
- else { NEXT(); RETURN_TOKEN(TK_DOUBLE_COLON); }
- case _SC('*'):
- NEXT();
- if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MULEQ);}
- else RETURN_TOKEN('*');
- case _SC('%'):
- NEXT();
- if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MODEQ);}
- else RETURN_TOKEN('%');
- case _SC('-'):
- NEXT();
- if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MINUSEQ);}
- else if (CUR_CHAR == _SC('-')){ NEXT(); RETURN_TOKEN(TK_MINUSMINUS);}
- else RETURN_TOKEN('-');
- case _SC('+'):
- NEXT();
- if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_PLUSEQ);}
- else if (CUR_CHAR == _SC('+')){ NEXT(); RETURN_TOKEN(TK_PLUSPLUS);}
- else RETURN_TOKEN('+');
- case SQUIRREL_EOB:
- return 0;
- default:{
- if (scisdigit(CUR_CHAR)) {
- SQInteger ret = ReadNumber();
- RETURN_TOKEN(ret);
- }
- else if (scisalpha(CUR_CHAR) || CUR_CHAR == _SC('_')) {
- SQInteger t = ReadID();
- RETURN_TOKEN(t);
- }
- else {
- SQInteger c = CUR_CHAR;
- if (sciscntrl((int)c)) Error(_SC("unexpected character(control)"));
- NEXT();
- RETURN_TOKEN(c);
- }
- RETURN_TOKEN(0);
- }
- }
- }
- return 0;
-}
-
-SQInteger SQLexer::GetIDType(SQChar *s)
-{
- SQObjectPtr t;
- if(_keywords->Get(SQString::Create(_sharedstate, s), t)) {
- return SQInteger(_integer(t));
- }
- return TK_IDENTIFIER;
-}
-
-
-SQInteger SQLexer::ReadString(SQInteger ndelim,bool verbatim)
-{
- INIT_TEMP_STRING();
- NEXT();
- if(IS_EOB()) return -1;
- for(;;) {
- while(CUR_CHAR != ndelim) {
- switch(CUR_CHAR) {
- case SQUIRREL_EOB:
- Error(_SC("unfinished string"));
- return -1;
- case _SC('\n'):
- if(!verbatim) Error(_SC("newline in a constant"));
- APPEND_CHAR(CUR_CHAR); NEXT();
- _currentline++;
- break;
- case _SC('\\'):
- if(verbatim) {
- APPEND_CHAR('\\'); NEXT();
- }
- else {
- NEXT();
- switch(CUR_CHAR) {
- case _SC('x'): NEXT(); {
- if(!isxdigit(CUR_CHAR)) Error(_SC("hexadecimal number expected"));
- const SQInteger maxdigits = 4;
- SQChar temp[maxdigits+1];
- SQInteger n = 0;
- while(isxdigit(CUR_CHAR) && n < maxdigits) {
- temp[n] = CUR_CHAR;
- n++;
- NEXT();
- }
- temp[n] = 0;
- SQChar *sTemp;
- APPEND_CHAR((SQChar)scstrtoul(temp,&sTemp,16));
- }
- break;
- case _SC('t'): APPEND_CHAR(_SC('\t')); NEXT(); break;
- case _SC('a'): APPEND_CHAR(_SC('\a')); NEXT(); break;
- case _SC('b'): APPEND_CHAR(_SC('\b')); NEXT(); break;
- case _SC('n'): APPEND_CHAR(_SC('\n')); NEXT(); break;
- case _SC('r'): APPEND_CHAR(_SC('\r')); NEXT(); break;
- case _SC('v'): APPEND_CHAR(_SC('\v')); NEXT(); break;
- case _SC('f'): APPEND_CHAR(_SC('\f')); NEXT(); break;
- case _SC('0'): APPEND_CHAR(_SC('\0')); NEXT(); break;
- case _SC('\\'): APPEND_CHAR(_SC('\\')); NEXT(); break;
- case _SC('"'): APPEND_CHAR(_SC('"')); NEXT(); break;
- case _SC('\''): APPEND_CHAR(_SC('\'')); NEXT(); break;
- default:
- Error(_SC("unrecognised escaper char"));
- break;
- }
- }
- break;
- default:
- APPEND_CHAR(CUR_CHAR);
- NEXT();
- }
- }
- NEXT();
- if(verbatim && CUR_CHAR == '"') { //double quotation
- APPEND_CHAR(CUR_CHAR);
- NEXT();
- }
- else {
- break;
- }
- }
- TERMINATE_BUFFER();
- SQInteger len = _longstr.size()-1;
- if(ndelim == _SC('\'')) {
- if(len == 0) Error(_SC("empty constant"));
- if(len > 1) Error(_SC("constant too long"));
- _nvalue = _longstr[0];
- return TK_INTEGER;
- }
- _svalue = &_longstr[0];
- return TK_STRING_LITERAL;
-}
-
-void LexHexadecimal(const SQChar *s,SQUnsignedInteger *res)
-{
- *res = 0;
- while(*s != 0)
- {
- if(scisdigit(*s)) *res = (*res)*16+((*s++)-'0');
- else if(scisxdigit(*s)) *res = (*res)*16+(toupper(*s++)-'A'+10);
- else { assert(0); }
- }
-}
-
-void LexInteger(const SQChar *s,SQUnsignedInteger *res)
-{
- *res = 0;
- while(*s != 0)
- {
- *res = (*res)*10+((*s++)-'0');
- }
-}
-
-SQInteger scisodigit(SQInteger c) { return c >= _SC('0') && c <= _SC('7'); }
-
-void LexOctal(const SQChar *s,SQUnsignedInteger *res)
-{
- *res = 0;
- while(*s != 0)
- {
- if(scisodigit(*s)) *res = (*res)*8+((*s++)-'0');
- else { assert(0); }
- }
-}
-
-SQInteger isexponent(SQInteger c) { return c == 'e' || c=='E'; }
-
-
-#define MAX_HEX_DIGITS (sizeof(SQInteger)*2)
-SQInteger SQLexer::ReadNumber()
-{
-#define TINT 1
-#define TFLOAT 2
-#define THEX 3
-#define TSCIENTIFIC 4
-#define TOCTAL 5
- SQInteger type = TINT, firstchar = CUR_CHAR;
- SQChar *sTemp;
- INIT_TEMP_STRING();
- NEXT();
- if(firstchar == _SC('0') && (toupper(CUR_CHAR) == _SC('X') || scisodigit(CUR_CHAR)) ) {
- if(scisodigit(CUR_CHAR)) {
- type = TOCTAL;
- while(scisodigit(CUR_CHAR)) {
- APPEND_CHAR(CUR_CHAR);
- NEXT();
- }
- if(scisdigit(CUR_CHAR)) Error(_SC("invalid octal number"));
- }
- else {
- NEXT();
- type = THEX;
- while(isxdigit(CUR_CHAR)) {
- APPEND_CHAR(CUR_CHAR);
- NEXT();
- }
- if(_longstr.size() > MAX_HEX_DIGITS) Error(_SC("too many digits for an Hex number"));
- }
- }
- else {
- APPEND_CHAR((int)firstchar);
- while (CUR_CHAR == _SC('.') || scisdigit(CUR_CHAR) || isexponent(CUR_CHAR)) {
- if(CUR_CHAR == _SC('.')) type = TFLOAT;
- if(isexponent(CUR_CHAR)) {
- if(type != TFLOAT) Error(_SC("invalid numeric format"));
- type = TSCIENTIFIC;
- APPEND_CHAR(CUR_CHAR);
- NEXT();
- if(CUR_CHAR == '+' || CUR_CHAR == '-'){
- APPEND_CHAR(CUR_CHAR);
- NEXT();
- }
- if(!scisdigit(CUR_CHAR)) Error(_SC("exponent expected"));
- }
-
- APPEND_CHAR(CUR_CHAR);
- NEXT();
- }
- }
- TERMINATE_BUFFER();
- switch(type) {
- case TSCIENTIFIC:
- case TFLOAT:
- _fvalue = (SQFloat)scstrtod(&_longstr[0],&sTemp);
- return TK_FLOAT;
- case TINT:
- LexInteger(&_longstr[0],(SQUnsignedInteger *)&_nvalue);
- return TK_INTEGER;
- case THEX:
- LexHexadecimal(&_longstr[0],(SQUnsignedInteger *)&_nvalue);
- return TK_INTEGER;
- case TOCTAL:
- LexOctal(&_longstr[0],(SQUnsignedInteger *)&_nvalue);
- return TK_INTEGER;
- }
- return 0;
-}
-
-SQInteger SQLexer::ReadID()
-{
- SQInteger res;
- INIT_TEMP_STRING();
- do {
- APPEND_CHAR(CUR_CHAR);
- NEXT();
- } while(scisalnum(CUR_CHAR) || CUR_CHAR == _SC('_'));
- TERMINATE_BUFFER();
- res = GetIDType(&_longstr[0]);
- if(res == TK_IDENTIFIER || res == TK_CONSTRUCTOR) {
- _svalue = &_longstr[0];
- }
- return res;
-}
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQLEXER_H_
-#define _SQLEXER_H_
-
-#ifdef SQUNICODE
-typedef SQChar LexChar;
-#else
-typedef unsigned char LexChar;
-#endif
-
-struct SQLexer
-{
- SQLexer();
- ~SQLexer();
- void Init(SQSharedState *ss,SQLEXREADFUNC rg,SQUserPointer up,CompilerErrorFunc efunc,void *ed);
- void Error(const SQChar *err);
- SQInteger Lex();
- const SQChar *Tok2Str(SQInteger tok);
-private:
- SQInteger GetIDType(SQChar *s);
- SQInteger ReadString(SQInteger ndelim,bool verbatim);
- SQInteger ReadNumber();
- void LexBlockComment();
- SQInteger ReadID();
- void Next();
- SQInteger _curtoken;
- SQTable *_keywords;
-public:
- SQInteger _prevtoken;
- SQInteger _currentline;
- SQInteger _lasttokenline;
- SQInteger _currentcolumn;
- const SQChar *_svalue;
- SQInteger _nvalue;
- SQFloat _fvalue;
- SQLEXREADFUNC _readf;
- SQUserPointer _up;
- LexChar _currdata;
- SQSharedState *_sharedstate;
- sqvector<SQChar> _longstr;
- CompilerErrorFunc _errfunc;
- void *_errtarget;
-};
-
-#endif
+++ /dev/null
-/*
- see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-void *sq_vm_malloc(SQUnsignedInteger size){ return malloc(size); }
-
-void *sq_vm_realloc(void *p, SQUnsignedInteger oldsize, SQUnsignedInteger size){ return realloc(p, size); }
-
-void sq_vm_free(void *p, SQUnsignedInteger size){ free(p); }
+++ /dev/null
-/*
- see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include "sqvm.h"
-#include "sqstring.h"
-#include "sqarray.h"
-#include "sqtable.h"
-#include "squserdata.h"
-#include "sqfuncproto.h"
-#include "sqclass.h"
-#include "sqclosure.h"
-
-
-const SQChar *IdType2Name(SQObjectType type)
-{
- switch(_RAW_TYPE(type))
- {
- case _RT_NULL:return _SC("null");
- case _RT_INTEGER:return _SC("integer");
- case _RT_FLOAT:return _SC("float");
- case _RT_BOOL:return _SC("bool");
- case _RT_STRING:return _SC("string");
- case _RT_TABLE:return _SC("table");
- case _RT_ARRAY:return _SC("array");
- case _RT_GENERATOR:return _SC("generator");
- case _RT_CLOSURE:
- case _RT_NATIVECLOSURE:
- return _SC("function");
- case _RT_USERDATA:
- case _RT_USERPOINTER:
- return _SC("userdata");
- case _RT_THREAD: return _SC("thread");
- case _RT_FUNCPROTO: return _SC("function");
- case _RT_CLASS: return _SC("class");
- case _RT_INSTANCE: return _SC("instance");
- case _RT_WEAKREF: return _SC("weakref");
- default:
- return NULL;
- }
-}
-
-const SQChar *GetTypeName(const SQObjectPtr &obj1)
-{
- return IdType2Name(type(obj1));
-}
-
-SQString *SQString::Create(SQSharedState *ss,const SQChar *s,SQInteger len)
-{
- SQString *str=ADD_STRING(ss,s,len);
- str->_sharedstate=ss;
- return str;
-}
-
-void SQString::Release()
-{
- REMOVE_STRING(_sharedstate,this);
-}
-
-SQInteger SQString::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval)
-{
- SQInteger idx = (SQInteger)TranslateIndex(refpos);
- while(idx < _len){
- outkey = (SQInteger)idx;
- outval = SQInteger(_val[idx]);
- //return idx for the next iteration
- return ++idx;
- }
- //nothing to iterate anymore
- return -1;
-}
-
-SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx)
-{
- switch(type(idx)){
- case OT_NULL:
- return 0;
- case OT_INTEGER:
- return (SQUnsignedInteger)_integer(idx);
- default: assert(0); break;
- }
- return 0;
-}
-
-SQWeakRef *SQRefCounted::GetWeakRef(SQObjectType type)
-{
- if(!_weakref) {
- sq_new(_weakref,SQWeakRef);
- _weakref->_obj._type = type;
- _weakref->_obj._unVal.pRefCounted = this;
- }
- return _weakref;
-}
-
-SQRefCounted::~SQRefCounted()
-{
- if(_weakref) {
- _weakref->_obj._type = OT_NULL;
- _weakref->_obj._unVal.pRefCounted = NULL;
- }
-}
-
-void SQWeakRef::Release() {
- if(ISREFCOUNTED(_obj._type)) {
- _obj._unVal.pRefCounted->_weakref = NULL;
- }
- sq_delete(this,SQWeakRef);
-}
-
-bool SQDelegable::GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res) {
- if(_delegate) {
- return _delegate->Get((*_ss(v)->_metamethods)[mm],res);
- }
- return false;
-}
-
-bool SQDelegable::SetDelegate(SQTable *mt)
-{
- SQTable *temp = mt;
- if(temp == this) return false;
- while (temp) {
- if (temp->_delegate == this) return false; //cycle detected
- temp = temp->_delegate;
- }
- if (mt) __ObjAddRef(mt);
- __ObjRelease(_delegate);
- _delegate = mt;
- return true;
-}
-
-bool SQGenerator::Yield(SQVM *v)
-{
- if(_state==eSuspended) { v->Raise_Error(_SC("internal vm error, yielding dead generator")); return false;}
- if(_state==eDead) { v->Raise_Error(_SC("internal vm error, yielding a dead generator")); return false; }
- SQInteger size = v->_top-v->_stackbase;
- _ci=*v->ci;
- _stack.resize(size);
- for(SQInteger n =0; n<size; n++) {
- _stack._vals[n] = v->_stack[v->_stackbase+n];
- v->_stack[v->_stackbase+n] = _null_;
- }
- SQInteger nvargs = v->ci->_vargs.size;
- SQInteger vargsbase = v->ci->_vargs.base;
- for(SQInteger j = nvargs - 1; j >= 0; j--) {
- _vargsstack.push_back(v->_vargsstack[vargsbase+j]);
- }
- _ci._generator=NULL;
- for(SQInteger i=0;i<_ci._etraps;i++) {
- _etraps.push_back(v->_etraps.top());
- v->_etraps.pop_back();
- }
- _state=eSuspended;
- return true;
-}
-
-bool SQGenerator::Resume(SQVM *v,SQInteger target)
-{
- SQInteger size=_stack.size();
- if(_state==eDead){ v->Raise_Error(_SC("resuming dead generator")); return false; }
- if(_state==eRunning){ v->Raise_Error(_SC("resuming active generator")); return false; }
- SQInteger prevtop=v->_top-v->_stackbase;
- PUSH_CALLINFO(v,_ci);
- SQInteger oldstackbase=v->_stackbase;
- v->_stackbase = v->_top;
- v->ci->_target = (SQInt32)target;
- v->ci->_generator = this;
- v->ci->_vargs.size = (unsigned short)_vargsstack.size();
-
- for(SQInteger i=0;i<_ci._etraps;i++) {
- v->_etraps.push_back(_etraps.top());
- _etraps.pop_back();
- }
- for(SQInteger n =0; n<size; n++) {
- v->_stack[v->_stackbase+n] = _stack._vals[n];
- _stack._vals[0] = _null_;
- }
- while(_vargsstack.size()) {
- v->_vargsstack.push_back(_vargsstack.back());
- _vargsstack.pop_back();
- }
- v->ci->_vargs.base = (unsigned short)(v->_vargsstack.size() - v->ci->_vargs.size);
- v->_top=v->_stackbase+size;
- v->ci->_prevtop = (SQInt32)prevtop;
- v->ci->_prevstkbase = (SQInt32)(v->_stackbase - oldstackbase);
- _state=eRunning;
- if (type(v->_debughook) != OT_NULL && _rawval(v->_debughook) != _rawval(v->ci->_closure))
- v->CallDebugHook(_SC('c'));
-
- return true;
-}
-
-void SQArray::Extend(const SQArray *a){
- SQInteger xlen;
- if((xlen=a->Size()))
- for(SQInteger i=0;i<xlen;i++)
- Append(a->_values[i]);
-}
-
-const SQChar* SQFunctionProto::GetLocal(SQVM *vm,SQUnsignedInteger stackbase,SQUnsignedInteger nseq,SQUnsignedInteger nop)
-{
- SQUnsignedInteger nvars=_nlocalvarinfos;
- const SQChar *res=NULL;
- if(nvars>=nseq){
- for(SQUnsignedInteger i=0;i<nvars;i++){
- if(_localvarinfos[i]._start_op<=nop && _localvarinfos[i]._end_op>=nop)
- {
- if(nseq==0){
- vm->Push(vm->_stack[stackbase+_localvarinfos[i]._pos]);
- res=_stringval(_localvarinfos[i]._name);
- break;
- }
- nseq--;
- }
- }
- }
- return res;
-}
-
-SQInteger SQFunctionProto::GetLine(SQInstruction *curr)
-{
- SQInteger op = (SQInteger)(curr-_instructions);
- SQInteger line=_lineinfos[0]._line;
- for(SQInteger i=1;i<_nlineinfos;i++){
- if(_lineinfos[i]._op>=op)
- return line;
- line=_lineinfos[i]._line;
- }
- return line;
-}
-
-#define _CHECK_IO(exp) { if(!exp)return false; }
-bool SafeWrite(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,SQUserPointer dest,SQInteger size)
-{
- if(write(up,dest,size) != size) {
- v->Raise_Error(_SC("io error (write function failure)"));
- return false;
- }
- return true;
-}
-
-bool SafeRead(HSQUIRRELVM v,SQWRITEFUNC read,SQUserPointer up,SQUserPointer dest,SQInteger size)
-{
- if(size && read(up,dest,size) != size) {
- v->Raise_Error(_SC("io error, read function failure, the origin stream could be corrupted/trucated"));
- return false;
- }
- return true;
-}
-
-bool WriteTag(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,SQInteger tag)
-{
- return SafeWrite(v,write,up,&tag,sizeof(tag));
-}
-
-bool CheckTag(HSQUIRRELVM v,SQWRITEFUNC read,SQUserPointer up,SQInteger tag)
-{
- SQInteger t;
- _CHECK_IO(SafeRead(v,read,up,&t,sizeof(t)));
- if(t != tag){
- v->Raise_Error(_SC("invalid or corrupted closure stream"));
- return false;
- }
- return true;
-}
-
-bool WriteObject(HSQUIRRELVM v,SQUserPointer up,SQWRITEFUNC write,SQObjectPtr &o)
-{
- _CHECK_IO(SafeWrite(v,write,up,&type(o),sizeof(SQObjectType)));
- switch(type(o)){
- case OT_STRING:
- _CHECK_IO(SafeWrite(v,write,up,&_string(o)->_len,sizeof(SQInteger)));
- _CHECK_IO(SafeWrite(v,write,up,_stringval(o),rsl(_string(o)->_len)));
- break;
- case OT_INTEGER:
- _CHECK_IO(SafeWrite(v,write,up,&_integer(o),sizeof(SQInteger)));break;
- case OT_FLOAT:
- _CHECK_IO(SafeWrite(v,write,up,&_float(o),sizeof(SQFloat)));break;
- case OT_NULL:
- break;
- default:
- v->Raise_Error(_SC("cannot serialize a %s"),GetTypeName(o));
- return false;
- }
- return true;
-}
-
-bool ReadObject(HSQUIRRELVM v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &o)
-{
- SQObjectType t;
- _CHECK_IO(SafeRead(v,read,up,&t,sizeof(SQObjectType)));
- switch(t){
- case OT_STRING:{
- SQInteger len;
- _CHECK_IO(SafeRead(v,read,up,&len,sizeof(SQInteger)));
- _CHECK_IO(SafeRead(v,read,up,_ss(v)->GetScratchPad(rsl(len)),rsl(len)));
- o=SQString::Create(_ss(v),_ss(v)->GetScratchPad(-1),len);
- }
- break;
- case OT_INTEGER:{
- SQInteger i;
- _CHECK_IO(SafeRead(v,read,up,&i,sizeof(SQInteger))); o = i; break;
- }
- case OT_FLOAT:{
- SQFloat f;
- _CHECK_IO(SafeRead(v,read,up,&f,sizeof(SQFloat))); o = f; break;
- }
- case OT_NULL:
- o=_null_;
- break;
- default:
- v->Raise_Error(_SC("cannot serialize a %s"),IdType2Name(t));
- return false;
- }
- return true;
-}
-
-bool SQClosure::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write)
-{
- _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_HEAD));
- _CHECK_IO(WriteTag(v,write,up,sizeof(SQChar)));
- _CHECK_IO(_funcproto(_function)->Save(v,up,write));
- _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_TAIL));
- return true;
-}
-
-bool SQClosure::Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret)
-{
- _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_HEAD));
- _CHECK_IO(CheckTag(v,read,up,sizeof(SQChar)));
- SQObjectPtr func;
- _CHECK_IO(SQFunctionProto::Load(v,up,read,func));
- _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_TAIL));
- ret = SQClosure::Create(_ss(v),_funcproto(func));
- return true;
-}
-
-bool SQFunctionProto::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write)
-{
- SQInteger i,nliterals = _nliterals,nparameters = _nparameters;
- SQInteger noutervalues = _noutervalues,nlocalvarinfos = _nlocalvarinfos;
- SQInteger nlineinfos=_nlineinfos,ninstructions = _ninstructions,nfunctions=_nfunctions;
- SQInteger ndefaultparams = _ndefaultparams;
- _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
- _CHECK_IO(WriteObject(v,up,write,_sourcename));
- _CHECK_IO(WriteObject(v,up,write,_name));
- _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
- _CHECK_IO(SafeWrite(v,write,up,&nliterals,sizeof(nliterals)));
- _CHECK_IO(SafeWrite(v,write,up,&nparameters,sizeof(nparameters)));
- _CHECK_IO(SafeWrite(v,write,up,&noutervalues,sizeof(noutervalues)));
- _CHECK_IO(SafeWrite(v,write,up,&nlocalvarinfos,sizeof(nlocalvarinfos)));
- _CHECK_IO(SafeWrite(v,write,up,&nlineinfos,sizeof(nlineinfos)));
- _CHECK_IO(SafeWrite(v,write,up,&ndefaultparams,sizeof(ndefaultparams)));
- _CHECK_IO(SafeWrite(v,write,up,&ninstructions,sizeof(ninstructions)));
- _CHECK_IO(SafeWrite(v,write,up,&nfunctions,sizeof(nfunctions)));
- _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
- for(i=0;i<nliterals;i++){
- _CHECK_IO(WriteObject(v,up,write,_literals[i]));
- }
-
- _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
- for(i=0;i<nparameters;i++){
- _CHECK_IO(WriteObject(v,up,write,_parameters[i]));
- }
-
- _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
- for(i=0;i<noutervalues;i++){
- _CHECK_IO(SafeWrite(v,write,up,&_outervalues[i]._type,sizeof(SQUnsignedInteger)));
- _CHECK_IO(WriteObject(v,up,write,_outervalues[i]._src));
- _CHECK_IO(WriteObject(v,up,write,_outervalues[i]._name));
- }
-
- _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
- for(i=0;i<nlocalvarinfos;i++){
- SQLocalVarInfo &lvi=_localvarinfos[i];
- _CHECK_IO(WriteObject(v,up,write,lvi._name));
- _CHECK_IO(SafeWrite(v,write,up,&lvi._pos,sizeof(SQUnsignedInteger)));
- _CHECK_IO(SafeWrite(v,write,up,&lvi._start_op,sizeof(SQUnsignedInteger)));
- _CHECK_IO(SafeWrite(v,write,up,&lvi._end_op,sizeof(SQUnsignedInteger)));
- }
-
- _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
- _CHECK_IO(SafeWrite(v,write,up,_lineinfos,sizeof(SQLineInfo)*nlineinfos));
-
- _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
- _CHECK_IO(SafeWrite(v,write,up,_defaultparams,sizeof(SQInteger)*ndefaultparams));
-
- _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
- _CHECK_IO(SafeWrite(v,write,up,_instructions,sizeof(SQInstruction)*ninstructions));
-
- _CHECK_IO(WriteTag(v,write,up,SQ_CLOSURESTREAM_PART));
- for(i=0;i<nfunctions;i++){
- _CHECK_IO(_funcproto(_functions[i])->Save(v,up,write));
- }
- _CHECK_IO(SafeWrite(v,write,up,&_stacksize,sizeof(_stacksize)));
- _CHECK_IO(SafeWrite(v,write,up,&_bgenerator,sizeof(_bgenerator)));
- _CHECK_IO(SafeWrite(v,write,up,&_varparams,sizeof(_varparams)));
- return true;
-}
-
-bool SQFunctionProto::Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &ret)
-{
- SQInteger i, nliterals,nparameters;
- SQInteger noutervalues ,nlocalvarinfos ;
- SQInteger nlineinfos,ninstructions ,nfunctions,ndefaultparams ;
- SQObjectPtr sourcename, name;
- SQObjectPtr o;
- _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
- _CHECK_IO(ReadObject(v, up, read, sourcename));
- _CHECK_IO(ReadObject(v, up, read, name));
-
- _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
- _CHECK_IO(SafeRead(v,read,up, &nliterals, sizeof(nliterals)));
- _CHECK_IO(SafeRead(v,read,up, &nparameters, sizeof(nparameters)));
- _CHECK_IO(SafeRead(v,read,up, &noutervalues, sizeof(noutervalues)));
- _CHECK_IO(SafeRead(v,read,up, &nlocalvarinfos, sizeof(nlocalvarinfos)));
- _CHECK_IO(SafeRead(v,read,up, &nlineinfos, sizeof(nlineinfos)));
- _CHECK_IO(SafeRead(v,read,up, &ndefaultparams, sizeof(ndefaultparams)));
- _CHECK_IO(SafeRead(v,read,up, &ninstructions, sizeof(ninstructions)));
- _CHECK_IO(SafeRead(v,read,up, &nfunctions, sizeof(nfunctions)));
-
-
- SQFunctionProto *f = SQFunctionProto::Create(ninstructions,nliterals,nparameters,
- nfunctions,noutervalues,nlineinfos,nlocalvarinfos,ndefaultparams);
- SQObjectPtr proto = f; //gets a ref in case of failure
- f->_sourcename = sourcename;
- f->_name = name;
-
- _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
-
- for(i = 0;i < nliterals; i++){
- _CHECK_IO(ReadObject(v, up, read, o));
- f->_literals[i] = o;
- }
- _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
-
- for(i = 0; i < nparameters; i++){
- _CHECK_IO(ReadObject(v, up, read, o));
- f->_parameters[i] = o;
- }
- _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
-
- for(i = 0; i < noutervalues; i++){
- SQUnsignedInteger type;
- SQObjectPtr name;
- _CHECK_IO(SafeRead(v,read,up, &type, sizeof(SQUnsignedInteger)));
- _CHECK_IO(ReadObject(v, up, read, o));
- _CHECK_IO(ReadObject(v, up, read, name));
- f->_outervalues[i] = SQOuterVar(name,o, (SQOuterType)type);
- }
- _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
-
- for(i = 0; i < nlocalvarinfos; i++){
- SQLocalVarInfo lvi;
- _CHECK_IO(ReadObject(v, up, read, lvi._name));
- _CHECK_IO(SafeRead(v,read,up, &lvi._pos, sizeof(SQUnsignedInteger)));
- _CHECK_IO(SafeRead(v,read,up, &lvi._start_op, sizeof(SQUnsignedInteger)));
- _CHECK_IO(SafeRead(v,read,up, &lvi._end_op, sizeof(SQUnsignedInteger)));
- f->_localvarinfos[i] = lvi;
- }
- _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
- _CHECK_IO(SafeRead(v,read,up, f->_lineinfos, sizeof(SQLineInfo)*nlineinfos));
-
- _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
- _CHECK_IO(SafeRead(v,read,up, f->_defaultparams, sizeof(SQInteger)*ndefaultparams));
-
- _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
- _CHECK_IO(SafeRead(v,read,up, f->_instructions, sizeof(SQInstruction)*ninstructions));
-
- _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART));
- for(i = 0; i < nfunctions; i++){
- _CHECK_IO(_funcproto(o)->Load(v, up, read, o));
- f->_functions[i] = o;
- }
- _CHECK_IO(SafeRead(v,read,up, &f->_stacksize, sizeof(f->_stacksize)));
- _CHECK_IO(SafeRead(v,read,up, &f->_bgenerator, sizeof(f->_bgenerator)));
- _CHECK_IO(SafeRead(v,read,up, &f->_varparams, sizeof(f->_varparams)));
-
- ret = f;
- return true;
-}
-
-#ifndef NO_GARBAGE_COLLECTOR
-
-#define START_MARK() if(!(_uiRef&MARK_FLAG)){ \
- _uiRef|=MARK_FLAG;
-
-#define END_MARK() RemoveFromChain(&_sharedstate->_gc_chain, this); \
- AddToChain(chain, this); }
-
-void SQVM::Mark(SQCollectable **chain)
-{
- START_MARK()
- SQSharedState::MarkObject(_lasterror,chain);
- SQSharedState::MarkObject(_errorhandler,chain);
- SQSharedState::MarkObject(_debughook,chain);
- SQSharedState::MarkObject(_roottable, chain);
- SQSharedState::MarkObject(temp_reg, chain);
- for(SQUnsignedInteger i = 0; i < _stack.size(); i++) SQSharedState::MarkObject(_stack[i], chain);
- for(SQUnsignedInteger j = 0; j < _vargsstack.size(); j++) SQSharedState::MarkObject(_vargsstack[j], chain);
- for(SQInteger k = 0; k < _callsstacksize; k++) SQSharedState::MarkObject(_callsstack[k]._closure, chain);
- END_MARK()
-}
-
-void SQArray::Mark(SQCollectable **chain)
-{
- START_MARK()
- SQInteger len = _values.size();
- for(SQInteger i = 0;i < len; i++) SQSharedState::MarkObject(_values[i], chain);
- END_MARK()
-}
-void SQTable::Mark(SQCollectable **chain)
-{
- START_MARK()
- if(_delegate) _delegate->Mark(chain);
- SQInteger len = _numofnodes;
- for(SQInteger i = 0; i < len; i++){
- SQSharedState::MarkObject(_nodes[i].key, chain);
- SQSharedState::MarkObject(_nodes[i].val, chain);
- }
- END_MARK()
-}
-
-void SQClass::Mark(SQCollectable **chain)
-{
- START_MARK()
- _members->Mark(chain);
- if(_base) _base->Mark(chain);
- SQSharedState::MarkObject(_attributes, chain);
- for(SQUnsignedInteger i =0; i< _defaultvalues.size(); i++) {
- SQSharedState::MarkObject(_defaultvalues[i].val, chain);
- SQSharedState::MarkObject(_defaultvalues[i].attrs, chain);
- }
- for(SQUnsignedInteger j =0; j< _methods.size(); j++) {
- SQSharedState::MarkObject(_methods[j].val, chain);
- SQSharedState::MarkObject(_methods[j].attrs, chain);
- }
- for(SQUnsignedInteger k =0; k< _metamethods.size(); k++) {
- SQSharedState::MarkObject(_metamethods[k], chain);
- }
- END_MARK()
-}
-
-void SQInstance::Mark(SQCollectable **chain)
-{
- START_MARK()
- _class->Mark(chain);
- SQUnsignedInteger nvalues = _class->_defaultvalues.size();
- for(SQUnsignedInteger i =0; i< nvalues; i++) {
- SQSharedState::MarkObject(_values[i], chain);
- }
- END_MARK()
-}
-
-void SQGenerator::Mark(SQCollectable **chain)
-{
- START_MARK()
- for(SQUnsignedInteger i = 0; i < _stack.size(); i++) SQSharedState::MarkObject(_stack[i], chain);
- for(SQUnsignedInteger j = 0; j < _vargsstack.size(); j++) SQSharedState::MarkObject(_vargsstack[j], chain);
- SQSharedState::MarkObject(_closure, chain);
- END_MARK()
-}
-
-void SQClosure::Mark(SQCollectable **chain)
-{
- START_MARK()
- for(SQUnsignedInteger i = 0; i < _outervalues.size(); i++) SQSharedState::MarkObject(_outervalues[i], chain);
- for(SQUnsignedInteger i = 0; i < _defaultparams.size(); i++) SQSharedState::MarkObject(_defaultparams[i], chain);
- END_MARK()
-}
-
-void SQNativeClosure::Mark(SQCollectable **chain)
-{
- START_MARK()
- for(SQUnsignedInteger i = 0; i < _outervalues.size(); i++) SQSharedState::MarkObject(_outervalues[i], chain);
- END_MARK()
-}
-
-void SQUserData::Mark(SQCollectable **chain){
- START_MARK()
- if(_delegate) _delegate->Mark(chain);
- END_MARK()
-}
-
-void SQCollectable::UnMark() { _uiRef&=~MARK_FLAG; }
-
-#endif
-
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQOBJECT_H_
-#define _SQOBJECT_H_
-
-#include "squtils.h"
-
-#define SQ_CLOSURESTREAM_HEAD (('S'<<24)|('Q'<<16)|('I'<<8)|('R'))
-#define SQ_CLOSURESTREAM_PART (('P'<<24)|('A'<<16)|('R'<<8)|('T'))
-#define SQ_CLOSURESTREAM_TAIL (('T'<<24)|('A'<<16)|('I'<<8)|('L'))
-
-struct SQSharedState;
-
-enum SQMetaMethod{
- MT_ADD=0,
- MT_SUB=1,
- MT_MUL=2,
- MT_DIV=3,
- MT_UNM=4,
- MT_MODULO=5,
- MT_SET=6,
- MT_GET=7,
- MT_TYPEOF=8,
- MT_NEXTI=9,
- MT_CMP=10,
- MT_CALL=11,
- MT_CLONED=12,
- MT_NEWSLOT=13,
- MT_DELSLOT=14,
- MT_TOSTRING=15,
- MT_NEWMEMBER=16,
- MT_INHERITED=17,
- MT_LAST = 18
-};
-
-#define MM_ADD _SC("_add")
-#define MM_SUB _SC("_sub")
-#define MM_MUL _SC("_mul")
-#define MM_DIV _SC("_div")
-#define MM_UNM _SC("_unm")
-#define MM_MODULO _SC("_modulo")
-#define MM_SET _SC("_set")
-#define MM_GET _SC("_get")
-#define MM_TYPEOF _SC("_typeof")
-#define MM_NEXTI _SC("_nexti")
-#define MM_CMP _SC("_cmp")
-#define MM_CALL _SC("_call")
-#define MM_CLONED _SC("_cloned")
-#define MM_NEWSLOT _SC("_newslot")
-#define MM_DELSLOT _SC("_delslot")
-#define MM_TOSTRING _SC("_tostring")
-#define MM_NEWMEMBER _SC("_newmember")
-#define MM_INHERITED _SC("_inherited")
-
-#define MINPOWER2 4
-
-struct SQRefCounted
-{
- SQRefCounted() { _uiRef = 0; _weakref = NULL; }
- virtual ~SQRefCounted();
- SQWeakRef *GetWeakRef(SQObjectType type);
- SQUnsignedInteger _uiRef;
- struct SQWeakRef *_weakref;
- virtual void Release()=0;
-};
-
-struct SQWeakRef : SQRefCounted
-{
- void Release();
- SQObject _obj;
-};
-
-#define _realval(o) (type((o)) != OT_WEAKREF?(SQObject)o:_weakref(o)->_obj)
-
-struct SQObjectPtr;
-
-#define __AddRef(type,unval) if(ISREFCOUNTED(type)) \
- { \
- unval.pRefCounted->_uiRef++; \
- }
-
-#define __Release(type,unval) if(ISREFCOUNTED(type) && ((--unval.pRefCounted->_uiRef)<=0)) \
- { \
- unval.pRefCounted->Release(); \
- }
-
-#define __ObjRelease(obj) { \
- if((obj)) { \
- (obj)->_uiRef--; \
- if((obj)->_uiRef == 0) \
- (obj)->Release(); \
- (obj) = NULL; \
- } \
-}
-
-#define __ObjAddRef(obj) { \
- (obj)->_uiRef++; \
-}
-
-#define type(obj) ((obj)._type)
-#define is_delegable(t) (type(t)&SQOBJECT_DELEGABLE)
-#define raw_type(obj) _RAW_TYPE((obj)._type)
-
-#define _integer(obj) ((obj)._unVal.nInteger)
-#define _float(obj) ((obj)._unVal.fFloat)
-#define _string(obj) ((obj)._unVal.pString)
-#define _table(obj) ((obj)._unVal.pTable)
-#define _array(obj) ((obj)._unVal.pArray)
-#define _closure(obj) ((obj)._unVal.pClosure)
-#define _generator(obj) ((obj)._unVal.pGenerator)
-#define _nativeclosure(obj) ((obj)._unVal.pNativeClosure)
-#define _userdata(obj) ((obj)._unVal.pUserData)
-#define _userpointer(obj) ((obj)._unVal.pUserPointer)
-#define _thread(obj) ((obj)._unVal.pThread)
-#define _funcproto(obj) ((obj)._unVal.pFunctionProto)
-#define _class(obj) ((obj)._unVal.pClass)
-#define _instance(obj) ((obj)._unVal.pInstance)
-#define _delegable(obj) ((SQDelegable *)(obj)._unVal.pDelegable)
-#define _weakref(obj) ((obj)._unVal.pWeakRef)
-#define _refcounted(obj) ((obj)._unVal.pRefCounted)
-#define _rawval(obj) ((obj)._unVal.raw)
-
-#define _stringval(obj) (obj)._unVal.pString->_val
-#define _userdataval(obj) (obj)._unVal.pUserData->_val
-
-#define tofloat(num) ((type(num)==OT_INTEGER)?(SQFloat)_integer(num):_float(num))
-#define tointeger(num) ((type(num)==OT_FLOAT)?(SQInteger)_float(num):_integer(num))
-/////////////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////////////
-struct SQObjectPtr : public SQObject
-{
- SQObjectPtr()
- {
- SQ_OBJECT_RAWINIT()
- _type=OT_NULL;
- _unVal.pUserPointer=NULL;
- }
- SQObjectPtr(const SQObjectPtr &o)
- {
- SQ_OBJECT_RAWINIT()
- _type=o._type;
- _unVal=o._unVal;
- __AddRef(_type,_unVal);
- }
- SQObjectPtr(const SQObject &o)
- {
- SQ_OBJECT_RAWINIT()
- _type=o._type;
- _unVal=o._unVal;
- __AddRef(_type,_unVal);
- }
- SQObjectPtr(SQTable *pTable)
- {
- SQ_OBJECT_RAWINIT()
- _type=OT_TABLE;
- _unVal.pTable=pTable;
- assert(_unVal.pTable);
- __AddRef(_type,_unVal);
- }
- SQObjectPtr(SQClass *pClass)
- {
- SQ_OBJECT_RAWINIT()
- _type=OT_CLASS;
- _unVal.pClass=pClass;
- assert(_unVal.pClass);
- __AddRef(_type,_unVal);
- }
- SQObjectPtr(SQInstance *pInstance)
- {
- SQ_OBJECT_RAWINIT()
- _type=OT_INSTANCE;
- _unVal.pInstance=pInstance;
- assert(_unVal.pInstance);
- __AddRef(_type,_unVal);
- }
- SQObjectPtr(SQArray *pArray)
- {
- SQ_OBJECT_RAWINIT()
- _type=OT_ARRAY;
- _unVal.pArray=pArray;
- assert(_unVal.pArray);
- __AddRef(_type,_unVal);
- }
- SQObjectPtr(SQClosure *pClosure)
- {
- SQ_OBJECT_RAWINIT()
- _type=OT_CLOSURE;
- _unVal.pClosure=pClosure;
- assert(_unVal.pClosure);
- __AddRef(_type,_unVal);
- }
- SQObjectPtr(SQGenerator *pGenerator)
- {
- SQ_OBJECT_RAWINIT()
- _type=OT_GENERATOR;
- _unVal.pGenerator=pGenerator;
- assert(_unVal.pGenerator);
- __AddRef(_type,_unVal);
- }
- SQObjectPtr(SQNativeClosure *pNativeClosure)
- {
- SQ_OBJECT_RAWINIT()
- _type=OT_NATIVECLOSURE;
- _unVal.pNativeClosure=pNativeClosure;
- assert(_unVal.pNativeClosure);
- __AddRef(_type,_unVal);
- }
- SQObjectPtr(SQString *pString)
- {
- SQ_OBJECT_RAWINIT()
- _type=OT_STRING;
- _unVal.pString=pString;
- assert(_unVal.pString);
- __AddRef(_type,_unVal);
- }
- SQObjectPtr(SQUserData *pUserData)
- {
- SQ_OBJECT_RAWINIT()
- _type=OT_USERDATA;
- _unVal.pUserData=pUserData;
- assert(_unVal.pUserData);
- __AddRef(_type,_unVal);
- }
- SQObjectPtr(SQVM *pThread)
- {
- SQ_OBJECT_RAWINIT()
- _type=OT_THREAD;
- _unVal.pThread=pThread;
- assert(_unVal.pThread);
- __AddRef(_type,_unVal);
- }
- SQObjectPtr(SQWeakRef *pWeakRef)
- {
- SQ_OBJECT_RAWINIT()
- _type=OT_WEAKREF;
- _unVal.pWeakRef=pWeakRef;
- assert(_unVal.pWeakRef);
- __AddRef(_type,_unVal);
- }
- SQObjectPtr(SQFunctionProto *pFunctionProto)
- {
- SQ_OBJECT_RAWINIT()
- _type=OT_FUNCPROTO;
- _unVal.pFunctionProto=pFunctionProto;
- assert(_unVal.pFunctionProto);
- __AddRef(_type,_unVal);
- }
- SQObjectPtr(SQInteger nInteger)
- {
- SQ_OBJECT_RAWINIT()
- _type=OT_INTEGER;
- _unVal.nInteger=nInteger;
- }
- SQObjectPtr(SQFloat fFloat)
- {
- SQ_OBJECT_RAWINIT()
- _type=OT_FLOAT;
- _unVal.fFloat=fFloat;
- }
- SQObjectPtr(bool bBool)
- {
- SQ_OBJECT_RAWINIT()
- _type = OT_BOOL;
- _unVal.nInteger = bBool?1:0;
- }
- SQObjectPtr(SQUserPointer pUserPointer)
- {
- SQ_OBJECT_RAWINIT()
- _type=OT_USERPOINTER;
- _unVal.pUserPointer=pUserPointer;
- }
- ~SQObjectPtr()
- {
- __Release(_type,_unVal);
- }
- inline void Null()
- {
- SQObjectType tOldType;
- SQObjectValue unOldVal;
- tOldType = _type;
- unOldVal = _unVal;
- _type = OT_NULL;
- _unVal.pUserPointer = NULL;
- __Release(tOldType,unOldVal);
- }
- inline SQObjectPtr& operator=(SQInteger i)
- {
- __Release(_type,_unVal);
- _unVal.nInteger = i;
- _type = OT_INTEGER;
- return *this;
- }
- inline SQObjectPtr& operator=(SQFloat f)
- {
- __Release(_type,_unVal);
- _unVal.fFloat = f;
- _type = OT_FLOAT;
- return *this;
- }
- inline SQObjectPtr& operator=(const SQObjectPtr& obj)
- {
- SQObjectType tOldType;
- SQObjectValue unOldVal;
- tOldType=_type;
- unOldVal=_unVal;
- _unVal = obj._unVal;
- _type = obj._type;
- __AddRef(_type,_unVal);
- __Release(tOldType,unOldVal);
- return *this;
- }
- inline SQObjectPtr& operator=(const SQObject& obj)
- {
- SQObjectType tOldType;
- SQObjectValue unOldVal;
- tOldType=_type;
- unOldVal=_unVal;
- _unVal = obj._unVal;
- _type = obj._type;
- __AddRef(_type,_unVal);
- __Release(tOldType,unOldVal);
- return *this;
- }
- private:
- SQObjectPtr(const SQChar *){} //safety
-};
-/////////////////////////////////////////////////////////////////////////////////////
-#ifndef NO_GARBAGE_COLLECTOR
-#define MARK_FLAG 0x80000000
-struct SQCollectable : public SQRefCounted {
- SQCollectable *_next;
- SQCollectable *_prev;
- SQSharedState *_sharedstate;
- virtual void Release()=0;
- virtual void Mark(SQCollectable **chain)=0;
- void UnMark();
- virtual void Finalize()=0;
- static void AddToChain(SQCollectable **chain,SQCollectable *c);
- static void RemoveFromChain(SQCollectable **chain,SQCollectable *c);
-};
-
-
-#define ADD_TO_CHAIN(chain,obj) AddToChain(chain,obj)
-#define REMOVE_FROM_CHAIN(chain,obj) {if(!(_uiRef&MARK_FLAG))RemoveFromChain(chain,obj);}
-#define CHAINABLE_OBJ SQCollectable
-#define INIT_CHAIN() {_next=NULL;_prev=NULL;_sharedstate=ss;}
-#else
-
-#define ADD_TO_CHAIN(chain,obj) ((void)0)
-#define REMOVE_FROM_CHAIN(chain,obj) ((void)0)
-#define CHAINABLE_OBJ SQRefCounted
-#define INIT_CHAIN() ((void)0)
-#endif
-
-struct SQDelegable : public CHAINABLE_OBJ {
- bool SetDelegate(SQTable *m);
- virtual bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res);
- SQTable *_delegate;
-};
-
-SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx);
-typedef sqvector<SQObjectPtr> SQObjectPtrVec;
-typedef sqvector<SQInteger> SQIntVec;
-const SQChar *GetTypeName(const SQObjectPtr &obj1);
-const SQChar *IdType2Name(SQObjectType type);
-
-
-
-#endif //_SQOBJECT_H_
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQOPCODES_H_
-#define _SQOPCODES_H_
-
-#define MAX_FUNC_STACKSIZE 0xFF
-#define MAX_LITERALS ((SQInteger)0x7FFFFFFF)
-
-enum BitWiseOP {
- BW_AND = 0,
- BW_OR = 2,
- BW_XOR = 3,
- BW_SHIFTL = 4,
- BW_SHIFTR = 5,
- BW_USHIFTR = 6
-};
-
-enum CmpOP {
- CMP_G = 0,
- CMP_GE = 2,
- CMP_L = 3,
- CMP_LE = 4
-};
-enum SQOpcode
-{
- _OP_LINE= 0x00,
- _OP_LOAD= 0x01,
- _OP_LOADINT= 0x02,
- _OP_LOADFLOAT= 0x03,
- _OP_DLOAD= 0x04,
- _OP_TAILCALL= 0x05,
- _OP_CALL= 0x06,
- _OP_PREPCALL= 0x07,
- _OP_PREPCALLK= 0x08,
- _OP_GETK= 0x09,
- _OP_MOVE= 0x0A,
- _OP_NEWSLOT= 0x0B,
- _OP_DELETE= 0x0C,
- _OP_SET= 0x0D,
- _OP_GET= 0x0E,
- _OP_EQ= 0x0F,
- _OP_NE= 0x10,
- _OP_ARITH= 0x11,
- _OP_BITW= 0x12,
- _OP_RETURN= 0x13,
- _OP_LOADNULLS= 0x14,
- _OP_LOADROOTTABLE= 0x15,
- _OP_LOADBOOL= 0x16,
- _OP_DMOVE= 0x17,
- _OP_JMP= 0x18,
- _OP_JNZ= 0x19,
- _OP_JZ= 0x1A,
- _OP_LOADFREEVAR= 0x1B,
- _OP_VARGC= 0x1C,
- _OP_GETVARGV= 0x1D,
- _OP_NEWTABLE= 0x1E,
- _OP_NEWARRAY= 0x1F,
- _OP_APPENDARRAY= 0x20,
- _OP_GETPARENT= 0x21,
- _OP_COMPARITH= 0x22,
- _OP_COMPARITHL= 0x23,
- _OP_INC= 0x24,
- _OP_INCL= 0x25,
- _OP_PINC= 0x26,
- _OP_PINCL= 0x27,
- _OP_CMP= 0x28,
- _OP_EXISTS= 0x29,
- _OP_INSTANCEOF= 0x2A,
- _OP_AND= 0x2B,
- _OP_OR= 0x2C,
- _OP_NEG= 0x2D,
- _OP_NOT= 0x2E,
- _OP_BWNOT= 0x2F,
- _OP_CLOSURE= 0x30,
- _OP_YIELD= 0x31,
- _OP_RESUME= 0x32,
- _OP_FOREACH= 0x33,
- _OP_POSTFOREACH= 0x34,
- _OP_DELEGATE= 0x35,
- _OP_CLONE= 0x36,
- _OP_TYPEOF= 0x37,
- _OP_PUSHTRAP= 0x38,
- _OP_POPTRAP= 0x39,
- _OP_THROW= 0x3A,
- _OP_CLASS= 0x3B,
- _OP_NEWSLOTA= 0x3C,
-};
-
-struct SQInstructionDesc {
- const SQChar *name;
-};
-
-struct SQInstruction
-{
- SQInstruction(){};
- SQInstruction(SQOpcode _op,SQInteger a0=0,SQInteger a1=0,SQInteger a2=0,SQInteger a3=0)
- { op = _op;
- _arg0 = (unsigned char)a0;_arg1 = (SQInt32)a1;
- _arg2 = (unsigned char)a2;_arg3 = (unsigned char)a3;
- }
-
-
- SQInt32 _arg1;
- unsigned char op;
- unsigned char _arg0;
- unsigned char _arg2;
- unsigned char _arg3;
-};
-
-#include "squtils.h"
-typedef sqvector<SQInstruction> SQInstructionVec;
-
-#define NEW_SLOT_ATTRIBUTES_FLAG 0x01
-#define NEW_SLOT_STATIC_FLAG 0x02
-
-#endif // _SQOPCODES_H_
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQPCHEADER_H_
-#define _SQPCHEADER_H_
-
-#if defined(_MSC_VER) && defined(_DEBUG)
-#include <crtdbg.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <new>
-//squirrel stuff
-#include <squirrel.h>
-#include "sqobject.h"
-#include "sqstate.h"
-
-#endif //_SQPCHEADER_H_
+++ /dev/null
-/*
- see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include "sqopcodes.h"
-#include "sqvm.h"
-#include "sqfuncproto.h"
-#include "sqclosure.h"
-#include "sqstring.h"
-#include "sqtable.h"
-#include "sqarray.h"
-#include "squserdata.h"
-#include "sqclass.h"
-
-SQObjectPtr _null_;
-SQObjectPtr _true_(true);
-SQObjectPtr _false_(false);
-SQObjectPtr _one_((SQInteger)1);
-SQObjectPtr _minusone_((SQInteger)-1);
-
-SQSharedState::SQSharedState()
-{
- _compilererrorhandler = NULL;
- _printfunc = NULL;
- _debuginfo = false;
- _notifyallexceptions = false;
-}
-
-#define newsysstring(s) { \
- _systemstrings->push_back(SQString::Create(this,s)); \
- }
-
-#define newmetamethod(s) { \
- _metamethods->push_back(SQString::Create(this,s)); \
- _table(_metamethodsmap)->NewSlot(_metamethods->back(),(SQInteger)(_metamethods->size()-1)); \
- }
-
-bool CompileTypemask(SQIntVec &res,const SQChar *typemask)
-{
- SQInteger i = 0;
-
- SQInteger mask = 0;
- while(typemask[i] != 0) {
-
- switch(typemask[i]){
- case 'o': mask |= _RT_NULL; break;
- case 'i': mask |= _RT_INTEGER; break;
- case 'f': mask |= _RT_FLOAT; break;
- case 'n': mask |= (_RT_FLOAT | _RT_INTEGER); break;
- case 's': mask |= _RT_STRING; break;
- case 't': mask |= _RT_TABLE; break;
- case 'a': mask |= _RT_ARRAY; break;
- case 'u': mask |= _RT_USERDATA; break;
- case 'c': mask |= (_RT_CLOSURE | _RT_NATIVECLOSURE); break;
- case 'b': mask |= _RT_BOOL; break;
- case 'g': mask |= _RT_GENERATOR; break;
- case 'p': mask |= _RT_USERPOINTER; break;
- case 'v': mask |= _RT_THREAD; break;
- case 'x': mask |= _RT_INSTANCE; break;
- case 'y': mask |= _RT_CLASS; break;
- case 'r': mask |= _RT_WEAKREF; break;
- case '.': mask = -1; res.push_back(mask); i++; mask = 0; continue;
- case ' ': i++; continue; //ignores spaces
- default:
- return false;
- }
- i++;
- if(typemask[i] == '|') {
- i++;
- if(typemask[i] == 0)
- return false;
- continue;
- }
- res.push_back(mask);
- mask = 0;
-
- }
- return true;
-}
-
-SQTable *CreateDefaultDelegate(SQSharedState *ss,SQRegFunction *funcz)
-{
- SQInteger i=0;
- SQTable *t=SQTable::Create(ss,0);
- while(funcz[i].name!=0){
- SQNativeClosure *nc = SQNativeClosure::Create(ss,funcz[i].f);
- nc->_nparamscheck = funcz[i].nparamscheck;
- nc->_name = SQString::Create(ss,funcz[i].name);
- if(funcz[i].typemask && !CompileTypemask(nc->_typecheck,funcz[i].typemask))
- return NULL;
- t->NewSlot(SQString::Create(ss,funcz[i].name),nc);
- i++;
- }
- return t;
-}
-
-void SQSharedState::Init()
-{
- _scratchpad=NULL;
- _scratchpadsize=0;
-#ifndef NO_GARBAGE_COLLECTOR
- _gc_chain=NULL;
-#endif
- sq_new(_stringtable,StringTable);
- sq_new(_metamethods,SQObjectPtrVec);
- sq_new(_systemstrings,SQObjectPtrVec);
- sq_new(_types,SQObjectPtrVec);
- _metamethodsmap = SQTable::Create(this,MT_LAST-1);
- //adding type strings to avoid memory trashing
- //types names
- newsysstring(_SC("null"));
- newsysstring(_SC("table"));
- newsysstring(_SC("array"));
- newsysstring(_SC("closure"));
- newsysstring(_SC("string"));
- newsysstring(_SC("userdata"));
- newsysstring(_SC("integer"));
- newsysstring(_SC("float"));
- newsysstring(_SC("userpointer"));
- newsysstring(_SC("function"));
- newsysstring(_SC("generator"));
- newsysstring(_SC("thread"));
- newsysstring(_SC("class"));
- newsysstring(_SC("instance"));
- newsysstring(_SC("bool"));
- //meta methods
- newmetamethod(MM_ADD);
- newmetamethod(MM_SUB);
- newmetamethod(MM_MUL);
- newmetamethod(MM_DIV);
- newmetamethod(MM_UNM);
- newmetamethod(MM_MODULO);
- newmetamethod(MM_SET);
- newmetamethod(MM_GET);
- newmetamethod(MM_TYPEOF);
- newmetamethod(MM_NEXTI);
- newmetamethod(MM_CMP);
- newmetamethod(MM_CALL);
- newmetamethod(MM_CLONED);
- newmetamethod(MM_NEWSLOT);
- newmetamethod(MM_DELSLOT);
- newmetamethod(MM_TOSTRING);
- newmetamethod(MM_NEWMEMBER);
- newmetamethod(MM_INHERITED);
-
- _constructoridx = SQString::Create(this,_SC("constructor"));
- _registry = SQTable::Create(this,0);
- _consts = SQTable::Create(this,0);
- _table_default_delegate = CreateDefaultDelegate(this,_table_default_delegate_funcz);
- _array_default_delegate = CreateDefaultDelegate(this,_array_default_delegate_funcz);
- _string_default_delegate = CreateDefaultDelegate(this,_string_default_delegate_funcz);
- _number_default_delegate = CreateDefaultDelegate(this,_number_default_delegate_funcz);
- _closure_default_delegate = CreateDefaultDelegate(this,_closure_default_delegate_funcz);
- _generator_default_delegate = CreateDefaultDelegate(this,_generator_default_delegate_funcz);
- _thread_default_delegate = CreateDefaultDelegate(this,_thread_default_delegate_funcz);
- _class_default_delegate = CreateDefaultDelegate(this,_class_default_delegate_funcz);
- _instance_default_delegate = CreateDefaultDelegate(this,_instance_default_delegate_funcz);
- _weakref_default_delegate = CreateDefaultDelegate(this,_weakref_default_delegate_funcz);
-
-}
-
-SQSharedState::~SQSharedState()
-{
- _constructoridx = _null_;
- _table(_registry)->Finalize();
- _table(_consts)->Finalize();
- _table(_metamethodsmap)->Finalize();
- _registry = _null_;
- _consts = _null_;
- _metamethodsmap = _null_;
- while(!_systemstrings->empty()) {
- _systemstrings->back()=_null_;
- _systemstrings->pop_back();
- }
- _thread(_root_vm)->Finalize();
- _root_vm = _null_;
- _table_default_delegate = _null_;
- _array_default_delegate = _null_;
- _string_default_delegate = _null_;
- _number_default_delegate = _null_;
- _closure_default_delegate = _null_;
- _generator_default_delegate = _null_;
- _thread_default_delegate = _null_;
- _class_default_delegate = _null_;
- _instance_default_delegate = _null_;
- _weakref_default_delegate = _null_;
- _refs_table.Finalize();
-#ifndef NO_GARBAGE_COLLECTOR
- SQCollectable *t = _gc_chain;
- SQCollectable *nx = NULL;
- while(t) {
- t->_uiRef++;
- t->Finalize();
- nx = t->_next;
- if(--t->_uiRef == 0)
- t->Release();
- t=nx;
- }
- assert(_gc_chain==NULL); //just to proove a theory
- while(_gc_chain){
- _gc_chain->_uiRef++;
- _gc_chain->Release();
- }
-#endif
-
- sq_delete(_types,SQObjectPtrVec);
- sq_delete(_systemstrings,SQObjectPtrVec);
- sq_delete(_metamethods,SQObjectPtrVec);
- sq_delete(_stringtable,StringTable);
- if(_scratchpad)SQ_FREE(_scratchpad,_scratchpadsize);
-}
-
-
-SQInteger SQSharedState::GetMetaMethodIdxByName(const SQObjectPtr &name)
-{
- if(type(name) != OT_STRING)
- return -1;
- SQObjectPtr ret;
- if(_table(_metamethodsmap)->Get(name,ret)) {
- return _integer(ret);
- }
- return -1;
-}
-
-#ifndef NO_GARBAGE_COLLECTOR
-
-void SQSharedState::MarkObject(SQObjectPtr &o,SQCollectable **chain)
-{
- switch(type(o)){
- case OT_TABLE:_table(o)->Mark(chain);break;
- case OT_ARRAY:_array(o)->Mark(chain);break;
- case OT_USERDATA:_userdata(o)->Mark(chain);break;
- case OT_CLOSURE:_closure(o)->Mark(chain);break;
- case OT_NATIVECLOSURE:_nativeclosure(o)->Mark(chain);break;
- case OT_GENERATOR:_generator(o)->Mark(chain);break;
- case OT_THREAD:_thread(o)->Mark(chain);break;
- case OT_CLASS:_class(o)->Mark(chain);break;
- case OT_INSTANCE:_instance(o)->Mark(chain);break;
- default: break; //shutup compiler
- }
-}
-
-
-SQInteger SQSharedState::CollectGarbage(SQVM *vm)
-{
- SQInteger n=0;
- SQCollectable *tchain=NULL;
- SQVM *vms = _thread(_root_vm);
-
- vms->Mark(&tchain);
- SQInteger x = _table(_thread(_root_vm)->_roottable)->CountUsed();
- _refs_table.Mark(&tchain);
- MarkObject(_registry,&tchain);
- MarkObject(_consts,&tchain);
- MarkObject(_metamethodsmap,&tchain);
- MarkObject(_table_default_delegate,&tchain);
- MarkObject(_array_default_delegate,&tchain);
- MarkObject(_string_default_delegate,&tchain);
- MarkObject(_number_default_delegate,&tchain);
- MarkObject(_generator_default_delegate,&tchain);
- MarkObject(_thread_default_delegate,&tchain);
- MarkObject(_closure_default_delegate,&tchain);
- MarkObject(_class_default_delegate,&tchain);
- MarkObject(_instance_default_delegate,&tchain);
- MarkObject(_weakref_default_delegate,&tchain);
-
- SQCollectable *t = _gc_chain;
- SQCollectable *nx = NULL;
- while(t) {
- t->_uiRef++;
- t->Finalize();
- nx = t->_next;
- if(--t->_uiRef == 0)
- t->Release();
- t = nx;
- n++;
- }
-
- t = tchain;
- while(t) {
- t->UnMark();
- t = t->_next;
- }
- _gc_chain = tchain;
- SQInteger z = _table(_thread(_root_vm)->_roottable)->CountUsed();
- assert(z == x);
- return n;
-}
-#endif
-
-#ifndef NO_GARBAGE_COLLECTOR
-void SQCollectable::AddToChain(SQCollectable **chain,SQCollectable *c)
-{
- c->_prev = NULL;
- c->_next = *chain;
- if(*chain) (*chain)->_prev = c;
- *chain = c;
-}
-
-void SQCollectable::RemoveFromChain(SQCollectable **chain,SQCollectable *c)
-{
- if(c->_prev) c->_prev->_next = c->_next;
- else *chain = c->_next;
- if(c->_next)
- c->_next->_prev = c->_prev;
- c->_next = NULL;
- c->_prev = NULL;
-}
-#endif
-
-SQChar* SQSharedState::GetScratchPad(SQInteger size)
-{
- SQInteger newsize;
- if(size>0) {
- if(_scratchpadsize < size) {
- newsize = size + (size>>1);
- _scratchpad = (SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize);
- _scratchpadsize = newsize;
-
- }else if(_scratchpadsize >= (size<<5)) {
- newsize = _scratchpadsize >> 1;
- _scratchpad = (SQChar *)SQ_REALLOC(_scratchpad,_scratchpadsize,newsize);
- _scratchpadsize = newsize;
- }
- }
- return _scratchpad;
-}
-
-RefTable::RefTable()
-{
- AllocNodes(4);
-}
-
-void RefTable::Finalize()
-{
- RefNode *nodes = _nodes;
- for(SQUnsignedInteger n = 0; n < _numofslots; n++) {
- nodes->obj = _null_;
- nodes++;
- }
-}
-
-RefTable::~RefTable()
-{
- SQ_FREE(_buckets,(_numofslots * sizeof(RefNode *)) + (_numofslots * sizeof(RefNode)));
-}
-
-#ifndef NO_GARBAGE_COLLECTOR
-void RefTable::Mark(SQCollectable **chain)
-{
- RefNode *nodes = (RefNode *)_nodes;
- for(SQUnsignedInteger n = 0; n < _numofslots; n++) {
- if(type(nodes->obj) != OT_NULL) {
- SQSharedState::MarkObject(nodes->obj,chain);
- }
- nodes++;
- }
-}
-#endif
-
-void RefTable::AddRef(SQObject &obj)
-{
- SQHash mainpos;
- RefNode *prev;
- RefNode *ref = Get(obj,mainpos,&prev,true);
- ref->refs++;
-}
-
-SQBool RefTable::Release(SQObject &obj)
-{
- SQHash mainpos;
- RefNode *prev;
- RefNode *ref = Get(obj,mainpos,&prev,false);
- if(ref) {
- if(--ref->refs == 0) {
- SQObjectPtr o = ref->obj;
- if(prev) {
- prev->next = ref->next;
- }
- else {
- _buckets[mainpos] = ref->next;
- }
- ref->next = _freelist;
- _freelist = ref;
- _slotused--;
- ref->obj = _null_;
- //<<FIXME>>test for shrink?
- return SQTrue;
- }
- }
- else {
- assert(0);
- }
- return SQFalse;
-}
-
-void RefTable::Resize(SQUnsignedInteger size)
-{
- RefNode **oldbucks = _buckets;
- RefNode *t = _nodes;
- SQUnsignedInteger oldnumofslots = _numofslots;
- AllocNodes(size);
- //rehash
- SQUnsignedInteger nfound = 0;
- for(SQUnsignedInteger n = 0; n < oldnumofslots; n++) {
- if(type(t->obj) != OT_NULL) {
- //add back;
- assert(t->refs != 0);
- RefNode *nn = Add(::HashObj(t->obj)&(_numofslots-1),t->obj);
- nn->refs = t->refs;
- t->obj = _null_;
- nfound++;
- }
- t++;
- }
- assert(nfound == oldnumofslots);
- SQ_FREE(oldbucks,(oldnumofslots * sizeof(RefNode *)) + (oldnumofslots * sizeof(RefNode)));
-}
-
-RefTable::RefNode *RefTable::Add(SQHash mainpos,SQObject &obj)
-{
- RefNode *t = _buckets[mainpos];
- RefNode *newnode = _freelist;
- newnode->obj = obj;
- _buckets[mainpos] = newnode;
- _freelist = _freelist->next;
- newnode->next = t;
- assert(newnode->refs == 0);
- _slotused++;
- return newnode;
-}
-
-RefTable::RefNode *RefTable::Get(SQObject &obj,SQHash &mainpos,RefNode **prev,bool add)
-{
- RefNode *ref;
- mainpos = ::HashObj(obj)&(_numofslots-1);
- *prev = NULL;
- for (ref = _buckets[mainpos]; ref; ) {
- if(_rawval(ref->obj) == _rawval(obj) && type(ref->obj) == type(obj))
- break;
- *prev = ref;
- ref = ref->next;
- }
- if(ref == NULL && add) {
- if(_numofslots == _slotused) {
- assert(_freelist == 0);
- Resize(_numofslots*2);
- mainpos = ::HashObj(obj)&(_numofslots-1);
- }
- ref = Add(mainpos,obj);
- }
- return ref;
-}
-
-void RefTable::AllocNodes(SQUnsignedInteger size)
-{
- RefNode **bucks;
- RefNode *nodes;
- bucks = (RefNode **)SQ_MALLOC((size * sizeof(RefNode *)) + (size * sizeof(RefNode)));
- nodes = (RefNode *)&bucks[size];
- RefNode *temp = nodes;
- SQUnsignedInteger n;
- for(n = 0; n < size - 1; n++) {
- bucks[n] = NULL;
- temp->refs = 0;
- new (&temp->obj) SQObjectPtr;
- temp->next = temp+1;
- temp++;
- }
- bucks[n] = NULL;
- temp->refs = 0;
- new (&temp->obj) SQObjectPtr;
- temp->next = NULL;
- _freelist = nodes;
- _nodes = nodes;
- _buckets = bucks;
- _slotused = 0;
- _numofslots = size;
-}
-//////////////////////////////////////////////////////////////////////////
-//StringTable
-/*
-* The following code is based on Lua 4.0 (Copyright 1994-2002 Tecgraf, PUC-Rio.)
-* http://www.lua.org/copyright.html#4
-* http://www.lua.org/source/4.0.1/src_lstring.c.html
-*/
-
-StringTable::StringTable()
-{
- AllocNodes(4);
- _slotused = 0;
-}
-
-StringTable::~StringTable()
-{
- SQ_FREE(_strings,sizeof(SQString*)*_numofslots);
- _strings = NULL;
-}
-
-void StringTable::AllocNodes(SQInteger size)
-{
- _numofslots = size;
- _strings = (SQString**)SQ_MALLOC(sizeof(SQString*)*_numofslots);
- memset(_strings,0,sizeof(SQString*)*_numofslots);
-}
-
-SQString *StringTable::Add(const SQChar *news,SQInteger len)
-{
- if(len<0)
- len = (SQInteger)scstrlen(news);
- SQHash h = ::_hashstr(news,len)&(_numofslots-1);
- SQString *s;
- for (s = _strings[h]; s; s = s->_next){
- if(s->_len == len && (!memcmp(news,s->_val,rsl(len))))
- return s; //found
- }
-
- SQString *t=(SQString *)SQ_MALLOC(rsl(len)+sizeof(SQString));
- new (t) SQString;
- memcpy(t->_val,news,rsl(len));
- t->_val[len] = _SC('\0');
- t->_len = len;
- t->_hash = ::_hashstr(news,len);
- t->_next = _strings[h];
- _strings[h] = t;
- _slotused++;
- if (_slotused > _numofslots) /* too crowded? */
- Resize(_numofslots*2);
- return t;
-}
-
-void StringTable::Resize(SQInteger size)
-{
- SQInteger oldsize=_numofslots;
- SQString **oldtable=_strings;
- AllocNodes(size);
- for (SQInteger i=0; i<oldsize; i++){
- SQString *p = oldtable[i];
- while(p){
- SQString *next = p->_next;
- SQHash h = p->_hash&(_numofslots-1);
- p->_next = _strings[h];
- _strings[h] = p;
- p = next;
- }
- }
- SQ_FREE(oldtable,oldsize*sizeof(SQString*));
-}
-
-void StringTable::Remove(SQString *bs)
-{
- SQString *s;
- SQString *prev=NULL;
- SQHash h = bs->_hash&(_numofslots - 1);
-
- for (s = _strings[h]; s; ){
- if(s == bs){
- if(prev)
- prev->_next = s->_next;
- else
- _strings[h] = s->_next;
- _slotused--;
- SQInteger slen = s->_len;
- s->~SQString();
- SQ_FREE(s,sizeof(SQString) + rsl(slen));
- return;
- }
- prev = s;
- s = s->_next;
- }
- assert(0);//if this fail something is wrong
-}
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQSTATE_H_
-#define _SQSTATE_H_
-
-#include "squtils.h"
-#include "sqobject.h"
-struct SQString;
-struct SQTable;
-//max number of character for a printed number
-#define NUMBER_MAX_CHAR 50
-
-struct StringTable
-{
- StringTable();
- ~StringTable();
- SQString *Add(const SQChar *,SQInteger len);
- void Remove(SQString *);
-private:
- void Resize(SQInteger size);
- void AllocNodes(SQInteger size);
- SQString **_strings;
- SQUnsignedInteger _numofslots;
- SQUnsignedInteger _slotused;
-};
-
-struct RefTable {
- struct RefNode {
- SQObjectPtr obj;
- SQUnsignedInteger refs;
- struct RefNode *next;
- };
- RefTable();
- ~RefTable();
- void AddRef(SQObject &obj);
- SQBool Release(SQObject &obj);
-#ifndef NO_GARBAGE_COLLECTOR
- void Mark(SQCollectable **chain);
-#endif
- void Finalize();
-private:
- RefNode *Get(SQObject &obj,SQHash &mainpos,RefNode **prev,bool add);
- RefNode *Add(SQHash mainpos,SQObject &obj);
- void Resize(SQUnsignedInteger size);
- void AllocNodes(SQUnsignedInteger size);
- SQUnsignedInteger _numofslots;
- SQUnsignedInteger _slotused;
- RefNode *_nodes;
- RefNode *_freelist;
- RefNode **_buckets;
-};
-
-#define ADD_STRING(ss,str,len) ss->_stringtable->Add(str,len)
-#define REMOVE_STRING(ss,bstr) ss->_stringtable->Remove(bstr)
-
-struct SQObjectPtr;
-
-struct SQSharedState
-{
- SQSharedState();
- ~SQSharedState();
- void Init();
-public:
- SQChar* GetScratchPad(SQInteger size);
- SQInteger GetMetaMethodIdxByName(const SQObjectPtr &name);
-#ifndef NO_GARBAGE_COLLECTOR
- SQInteger CollectGarbage(SQVM *vm);
- static void MarkObject(SQObjectPtr &o,SQCollectable **chain);
-#endif
- SQObjectPtrVec *_metamethods;
- SQObjectPtr _metamethodsmap;
- SQObjectPtrVec *_systemstrings;
- SQObjectPtrVec *_types;
- StringTable *_stringtable;
- RefTable _refs_table;
- SQObjectPtr _registry;
- SQObjectPtr _consts;
- SQObjectPtr _constructoridx;
-#ifndef NO_GARBAGE_COLLECTOR
- SQCollectable *_gc_chain;
-#endif
- SQObjectPtr _root_vm;
- SQObjectPtr _table_default_delegate;
- static SQRegFunction _table_default_delegate_funcz[];
- SQObjectPtr _array_default_delegate;
- static SQRegFunction _array_default_delegate_funcz[];
- SQObjectPtr _string_default_delegate;
- static SQRegFunction _string_default_delegate_funcz[];
- SQObjectPtr _number_default_delegate;
- static SQRegFunction _number_default_delegate_funcz[];
- SQObjectPtr _generator_default_delegate;
- static SQRegFunction _generator_default_delegate_funcz[];
- SQObjectPtr _closure_default_delegate;
- static SQRegFunction _closure_default_delegate_funcz[];
- SQObjectPtr _thread_default_delegate;
- static SQRegFunction _thread_default_delegate_funcz[];
- SQObjectPtr _class_default_delegate;
- static SQRegFunction _class_default_delegate_funcz[];
- SQObjectPtr _instance_default_delegate;
- static SQRegFunction _instance_default_delegate_funcz[];
- SQObjectPtr _weakref_default_delegate;
- static SQRegFunction _weakref_default_delegate_funcz[];
-
- SQCOMPILERERROR _compilererrorhandler;
- SQPRINTFUNCTION _printfunc;
- bool _debuginfo;
- bool _notifyallexceptions;
-private:
- SQChar *_scratchpad;
- SQInteger _scratchpadsize;
-};
-
-#define _sp(s) (_sharedstate->GetScratchPad(s))
-#define _spval (_sharedstate->GetScratchPad(-1))
-
-#define _table_ddel _table(_sharedstate->_table_default_delegate)
-#define _array_ddel _table(_sharedstate->_array_default_delegate)
-#define _string_ddel _table(_sharedstate->_string_default_delegate)
-#define _number_ddel _table(_sharedstate->_number_default_delegate)
-#define _generator_ddel _table(_sharedstate->_generator_default_delegate)
-#define _closure_ddel _table(_sharedstate->_closure_default_delegate)
-#define _thread_ddel _table(_sharedstate->_thread_default_delegate)
-#define _class_ddel _table(_sharedstate->_class_default_delegate)
-#define _instance_ddel _table(_sharedstate->_instance_default_delegate)
-#define _weakref_ddel _table(_sharedstate->_weakref_default_delegate)
-
-#ifdef SQUNICODE //rsl REAL STRING LEN
-#define rsl(l) ((l)<<1)
-#else
-#define rsl(l) (l)
-#endif
-
-extern SQObjectPtr _null_;
-extern SQObjectPtr _true_;
-extern SQObjectPtr _false_;
-extern SQObjectPtr _one_;
-extern SQObjectPtr _minusone_;
-
-bool CompileTypemask(SQIntVec &res,const SQChar *typemask);
-
-void *sq_vm_malloc(SQUnsignedInteger size);
-void *sq_vm_realloc(void *p,SQUnsignedInteger oldsize,SQUnsignedInteger size);
-void sq_vm_free(void *p,SQUnsignedInteger size);
-#endif //_SQSTATE_H_
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQSTRING_H_
-#define _SQSTRING_H_
-
-inline SQHash _hashstr (const SQChar *s, size_t l)
-{
- SQHash h = (SQHash)l; /* seed */
- size_t step = (l>>5)|1; /* if string is too long, don't hash all its chars */
- for (; l>=step; l-=step)
- h = h ^ ((h<<5)+(h>>2)+(unsigned short)*(s++));
- return h;
-}
-
-struct SQString : public SQRefCounted
-{
- SQString(){}
- ~SQString(){}
-public:
- static SQString *Create(SQSharedState *ss, const SQChar *, SQInteger len = -1 );
- SQInteger Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);
- void Release();
- SQSharedState *_sharedstate;
- SQString *_next; //chain for the string table
- SQInteger _len;
- SQHash _hash;
- SQChar _val[1];
-};
-
-
-
-#endif //_SQSTRING_H_
+++ /dev/null
-/*
-see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include "sqvm.h"
-#include "sqtable.h"
-#include "sqfuncproto.h"
-#include "sqclosure.h"
-
-SQTable::SQTable(SQSharedState *ss,SQInteger nInitialSize)
-{
- SQInteger pow2size=MINPOWER2;
- while(nInitialSize>pow2size)pow2size=pow2size<<1;
- AllocNodes(pow2size);
- _usednodes = 0;
- _delegate = NULL;
- INIT_CHAIN();
- ADD_TO_CHAIN(&_sharedstate->_gc_chain,this);
-}
-
-void SQTable::Remove(const SQObjectPtr &key)
-{
-
- _HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1));
- if (n) {
- n->val = n->key = _null_;
- _usednodes--;
- Rehash(false);
- }
-}
-
-void SQTable::AllocNodes(SQInteger nSize)
-{
- _HashNode *nodes=(_HashNode *)SQ_MALLOC(sizeof(_HashNode)*nSize);
- for(SQInteger i=0;i<nSize;i++){
- new (&nodes[i]) _HashNode;
- nodes[i].next=NULL;
- }
- _numofnodes=nSize;
- _nodes=nodes;
- _firstfree=&_nodes[_numofnodes-1];
-}
-
-void SQTable::Rehash(bool force)
-{
- SQInteger oldsize=_numofnodes;
- //prevent problems with the integer division
- if(oldsize<4)oldsize=4;
- _HashNode *nold=_nodes;
- SQInteger nelems=CountUsed();
- if (nelems >= oldsize-oldsize/4) /* using more than 3/4? */
- AllocNodes(oldsize*2);
- else if (nelems <= oldsize/4 && /* less than 1/4? */
- oldsize > MINPOWER2)
- AllocNodes(oldsize/2);
- else if(force)
- AllocNodes(oldsize);
- else
- return;
- _usednodes = 0;
- for (SQInteger i=0; i<oldsize; i++) {
- _HashNode *old = nold+i;
- if (type(old->key) != OT_NULL)
- NewSlot(old->key,old->val);
- }
- for(SQInteger k=0;k<oldsize;k++)
- nold[k].~_HashNode();
- SQ_FREE(nold,oldsize*sizeof(_HashNode));
-}
-
-SQTable *SQTable::Clone()
-{
- SQTable *nt=Create(_opt_ss(this),_numofnodes);
- SQInteger ridx=0;
- SQObjectPtr key,val;
- while((ridx=Next(true,ridx,key,val))!=-1){
- nt->NewSlot(key,val);
- }
- nt->SetDelegate(_delegate);
- return nt;
-}
-
-bool SQTable::Get(const SQObjectPtr &key,SQObjectPtr &val)
-{
- if(type(key) == OT_NULL)
- return false;
- _HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1));
- if (n) {
- val = _realval(n->val);
- return true;
- }
- return false;
-}
-bool SQTable::NewSlot(const SQObjectPtr &key,const SQObjectPtr &val)
-{
- assert(type(key) != OT_NULL);
- SQHash h = HashObj(key) & (_numofnodes - 1);
- _HashNode *n = _Get(key, h);
- if (n) {
- n->val = val;
- return false;
- }
- _HashNode *mp = &_nodes[h];
- n = mp;
-
-
- //key not found I'll insert it
- //main pos is not free
-
- if(type(mp->key) != OT_NULL) {
- n = _firstfree; /* get a free place */
- SQHash mph = HashObj(mp->key) & (_numofnodes - 1);
- _HashNode *othern; /* main position of colliding node */
-
- if (mp > n && (othern = &_nodes[mph]) != mp){
- /* yes; move colliding node into free position */
- while (othern->next != mp){
- assert(othern->next != NULL);
- othern = othern->next; /* find previous */
- }
- othern->next = n; /* redo the chain with `n' in place of `mp' */
- n->key = mp->key;
- n->val = mp->val;/* copy colliding node into free pos. (mp->next also goes) */
- n->next = mp->next;
- mp->key = _null_;
- mp->val = _null_;
- mp->next = NULL; /* now `mp' is free */
- }
- else{
- /* new node will go into free position */
- n->next = mp->next; /* chain new position */
- mp->next = n;
- mp = n;
- }
- }
- mp->key = key;
-
- for (;;) { /* correct `firstfree' */
- if (type(_firstfree->key) == OT_NULL && _firstfree->next == NULL) {
- mp->val = val;
- _usednodes++;
- return true; /* OK; table still has a free place */
- }
- else if (_firstfree == _nodes) break; /* cannot decrement from here */
- else (_firstfree)--;
- }
- Rehash(true);
- return NewSlot(key, val);
-}
-
-SQInteger SQTable::Next(bool getweakrefs,const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval)
-{
- SQInteger idx = (SQInteger)TranslateIndex(refpos);
- while (idx < _numofnodes) {
- if(type(_nodes[idx].key) != OT_NULL) {
- //first found
- _HashNode &n = _nodes[idx];
- outkey = n.key;
- outval = getweakrefs?(SQObject)n.val:_realval(n.val);
- //return idx for the next iteration
- return ++idx;
- }
- ++idx;
- }
- //nothing to iterate anymore
- return -1;
-}
-
-
-bool SQTable::Set(const SQObjectPtr &key, const SQObjectPtr &val)
-{
- _HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1));
- if (n) {
- n->val = val;
- return true;
- }
- return false;
-}
-
-void SQTable::_ClearNodes()
-{
- for(SQInteger i = 0;i < _numofnodes; i++) { _nodes[i].key = _null_; _nodes[i].val = _null_; }
-}
-
-void SQTable::Finalize()
-{
- _ClearNodes();
- SetDelegate(NULL);
-}
-
-void SQTable::Clear()
-{
- _ClearNodes();
- _usednodes = 0;
- Rehash(true);
-}
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQTABLE_H_
-#define _SQTABLE_H_
-/*
-* The following code is based on Lua 4.0 (Copyright 1994-2002 Tecgraf, PUC-Rio.)
-* http://www.lua.org/copyright.html#4
-* http://www.lua.org/source/4.0.1/src_ltable.c.html
-*/
-
-#include "sqstring.h"
-
-
-#define hashptr(p) ((SQHash)(((SQInteger)p) >> 3))
-
-inline SQHash HashObj(const SQObjectPtr &key)
-{
- switch(type(key)) {
- case OT_STRING: return _string(key)->_hash;
- case OT_FLOAT: return (SQHash)((SQInteger)_float(key));
- case OT_BOOL: case OT_INTEGER: return (SQHash)((SQInteger)_integer(key));
- default: return hashptr(key._unVal.pRefCounted);
- }
-}
-
-struct SQTable : public SQDelegable
-{
-private:
- struct _HashNode
- {
- _HashNode() { next = NULL; }
- SQObjectPtr val;
- SQObjectPtr key;
- _HashNode *next;
- };
- _HashNode *_firstfree;
- _HashNode *_nodes;
- SQInteger _numofnodes;
- SQInteger _usednodes;
-
-///////////////////////////
- void AllocNodes(SQInteger nSize);
- void Rehash(bool force);
- SQTable(SQSharedState *ss, SQInteger nInitialSize);
- void _ClearNodes();
-public:
- static SQTable* Create(SQSharedState *ss,SQInteger nInitialSize)
- {
- SQTable *newtable = (SQTable*)SQ_MALLOC(sizeof(SQTable));
- new (newtable) SQTable(ss, nInitialSize);
- newtable->_delegate = NULL;
- return newtable;
- }
- void Finalize();
- SQTable *Clone();
- ~SQTable()
- {
- SetDelegate(NULL);
- REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
- for (SQInteger i = 0; i < _numofnodes; i++) _nodes[i].~_HashNode();
- SQ_FREE(_nodes, _numofnodes * sizeof(_HashNode));
- }
-#ifndef NO_GARBAGE_COLLECTOR
- void Mark(SQCollectable **chain);
-#endif
- inline _HashNode *_Get(const SQObjectPtr &key,SQHash hash)
- {
- _HashNode *n = &_nodes[hash];
- do{
- if(_rawval(n->key) == _rawval(key) && type(n->key) == type(key)){
- return n;
- }
- }while((n = n->next));
- return NULL;
- }
- bool Get(const SQObjectPtr &key,SQObjectPtr &val);
- void Remove(const SQObjectPtr &key);
- bool Set(const SQObjectPtr &key, const SQObjectPtr &val);
- //returns true if a new slot has been created false if it was already present
- bool NewSlot(const SQObjectPtr &key,const SQObjectPtr &val);
- SQInteger Next(bool getweakrefs,const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);
-
- SQInteger CountUsed(){ return _usednodes;}
- void Clear();
- void Release()
- {
- sq_delete(this, SQTable);
- }
-
-};
-
-#endif //_SQTABLE_H_
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQUSERDATA_H_
-#define _SQUSERDATA_H_
-
-struct SQUserData : SQDelegable
-{
- SQUserData(SQSharedState *ss){ _delegate = 0; _hook = NULL; INIT_CHAIN(); ADD_TO_CHAIN(&_ss(this)->_gc_chain, this); }
- ~SQUserData()
- {
- REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain, this);
- SetDelegate(NULL);
- }
- static SQUserData* Create(SQSharedState *ss, SQInteger size)
- {
- SQUserData* ud = (SQUserData*)SQ_MALLOC(sizeof(SQUserData)+(size-1));
- new (ud) SQUserData(ss);
- ud->_size = size;
- ud->_typetag = 0;
- return ud;
- }
-#ifndef NO_GARBAGE_COLLECTOR
- void Mark(SQCollectable **chain);
- void Finalize(){SetDelegate(NULL);}
-#endif
- void Release() {
- if (_hook) _hook(_val,_size);
- SQInteger tsize = _size - 1;
- this->~SQUserData();
- SQ_FREE(this, sizeof(SQUserData) + tsize);
- }
-
- SQInteger _size;
- SQRELEASEHOOK _hook;
- SQUserPointer _typetag;
- SQChar _val[1];
-};
-
-#endif //_SQUSERDATA_H_
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQUTILS_H_
-#define _SQUTILS_H_
-
-#define sq_new(__ptr,__type) {__ptr=(__type *)sq_vm_malloc(sizeof(__type));new (__ptr) __type;}
-#define sq_delete(__ptr,__type) {__ptr->~__type();sq_vm_free(__ptr,sizeof(__type));}
-#define SQ_MALLOC(__size) sq_vm_malloc((__size));
-#define SQ_FREE(__ptr,__size) sq_vm_free((__ptr),(__size));
-#define SQ_REALLOC(__ptr,__oldsize,__size) sq_vm_realloc((__ptr),(__oldsize),(__size));
-
-//sqvector mini vector class, supports objects by value
-template<typename T> class sqvector
-{
-public:
- sqvector()
- {
- _vals = NULL;
- _size = 0;
- _allocated = 0;
- }
- sqvector(const sqvector<T>& v)
- {
- copy(v);
- }
- void copy(const sqvector<T>& v)
- {
- resize(v._size);
- for(SQUnsignedInteger i = 0; i < v._size; i++) {
- new ((void *)&_vals[i]) T(v._vals[i]);
- }
- _size = v._size;
- }
- ~sqvector()
- {
- if(_allocated) {
- for(SQUnsignedInteger i = 0; i < _size; i++)
- _vals[i].~T();
- SQ_FREE(_vals, (_allocated * sizeof(T)));
- }
- }
- void reserve(SQUnsignedInteger newsize) { _realloc(newsize); }
- void resize(SQUnsignedInteger newsize, const T& fill = T())
- {
- if(newsize > _allocated)
- _realloc(newsize);
- if(newsize > _size) {
- while(_size < newsize) {
- new ((void *)&_vals[_size]) T(fill);
- _size++;
- }
- }
- else{
- for(SQUnsignedInteger i = newsize; i < _size; i++) {
- _vals[i].~T();
- }
- _size = newsize;
- }
- }
- void shrinktofit() { if(_size > 4) { _realloc(_size); } }
- T& top() const { return _vals[_size - 1]; }
- inline SQUnsignedInteger size() const { return _size; }
- bool empty() const { return (_size <= 0); }
- inline T &push_back(const T& val = T())
- {
- if(_allocated <= _size)
- _realloc(_size * 2);
- return *(new ((void *)&_vals[_size++]) T(val));
- }
- inline void pop_back()
- {
- _size--; _vals[_size].~T();
- }
- void insert(SQUnsignedInteger idx, const T& val)
- {
- resize(_size + 1);
- for(SQUnsignedInteger i = _size - 1; i > idx; i--) {
- _vals[i] = _vals[i - 1];
- }
- _vals[idx] = val;
- }
- void remove(SQUnsignedInteger idx)
- {
- _vals[idx].~T();
- if(idx < (_size - 1)) {
- memmove(&_vals[idx], &_vals[idx+1], sizeof(T) * (_size - idx - 1));
- }
- _size--;
- }
- SQUnsignedInteger capacity() { return _allocated; }
- inline T &back() const { return _vals[_size - 1]; }
- inline T& operator[](SQUnsignedInteger pos) const{ return _vals[pos]; }
- T* _vals;
-private:
- void _realloc(SQUnsignedInteger newsize)
- {
- newsize = (newsize > 0)?newsize:4;
- _vals = (T*)SQ_REALLOC(_vals, _allocated * sizeof(T), newsize * sizeof(T));
- _allocated = newsize;
- }
- SQUnsignedInteger _size;
- SQUnsignedInteger _allocated;
-};
-
-#endif //_SQUTILS_H_
+++ /dev/null
-/*
- see copyright notice in squirrel.h
-*/
-#include "sqpcheader.h"
-#include <math.h>
-#include <stdlib.h>
-#include "sqopcodes.h"
-#include "sqfuncproto.h"
-#include "sqvm.h"
-#include "sqclosure.h"
-#include "sqstring.h"
-#include "sqtable.h"
-#include "squserdata.h"
-#include "sqarray.h"
-#include "sqclass.h"
-
-#define TOP() (_stack._vals[_top-1])
-
-#define CLEARSTACK(_last_top) { if((_last_top) >= _top) ClearStack(_last_top); }
-void SQVM::ClearStack(SQInteger last_top)
-{
- SQObjectType tOldType;
- SQObjectValue unOldVal;
- while (last_top >= _top) {
- SQObjectPtr &o = _stack._vals[last_top--];
- tOldType = o._type;
- unOldVal = o._unVal;
- o._type = OT_NULL;
- o._unVal.pUserPointer = NULL;
- __Release(tOldType,unOldVal);
- }
-}
-
-bool SQVM::BW_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2)
-{
- SQInteger res;
- SQInteger i1 = _integer(o1), i2 = _integer(o2);
- if((type(o1)==OT_INTEGER) && (type(o2)==OT_INTEGER))
- {
- switch(op) {
- case BW_AND: res = i1 & i2; break;
- case BW_OR: res = i1 | i2; break;
- case BW_XOR: res = i1 ^ i2; break;
- case BW_SHIFTL: res = i1 << i2; break;
- case BW_SHIFTR: res = i1 >> i2; break;
- case BW_USHIFTR:res = (SQInteger)(*((SQUnsignedInteger*)&i1) >> i2); break;
- default: { Raise_Error(_SC("internal vm error bitwise op failed")); return false; }
- }
- }
- else { Raise_Error(_SC("bitwise op between '%s' and '%s'"),GetTypeName(o1),GetTypeName(o2)); return false;}
- trg = res;
- return true;
-}
-
-bool SQVM::ARITH_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2)
-{
- if(sq_isnumeric(o1) && sq_isnumeric(o2)) {
- if((type(o1)==OT_INTEGER) && (type(o2)==OT_INTEGER)) {
- SQInteger res, i1 = _integer(o1), i2 = _integer(o2);
- switch(op) {
- case '+': res = i1 + i2; break;
- case '-': res = i1 - i2; break;
- case '/': if(i2 == 0) { Raise_Error(_SC("division by zero")); return false; }
- res = i1 / i2;
- break;
- case '*': res = i1 * i2; break;
- case '%': if(i2 == 0) { Raise_Error(_SC("modulo by zero")); return false; }
- res = i1 % i2;
- break;
- default: res = 0xDEADBEEF;
- }
- trg = res;
- }else{
- SQFloat res, f1 = tofloat(o1), f2 = tofloat(o2);
- switch(op) {
- case '+': res = f1 + f2; break;
- case '-': res = f1 - f2; break;
- case '/': res = f1 / f2; break;
- case '*': res = f1 * f2; break;
- case '%': res = SQFloat(fmod((double)f1,(double)f2)); break;
- default: res = 0x0f;
- }
- trg = res;
- }
- } else {
- if(op == '+' && (type(o1) == OT_STRING || type(o2) == OT_STRING)){
- if(!StringCat(o1, o2, trg)) return false;
- }
- else if(!ArithMetaMethod(op,o1,o2,trg)) {
- Raise_Error(_SC("arith op %c on between '%s' and '%s'"),op,GetTypeName(o1),GetTypeName(o2)); return false;
- }
- }
- return true;
-}
-
-SQVM::SQVM(SQSharedState *ss)
-{
- _sharedstate=ss;
- _suspended = SQFalse;
- _suspended_target=-1;
- _suspended_root = SQFalse;
- _suspended_traps=-1;
- _foreignptr=NULL;
- _nnativecalls=0;
- _lasterror = _null_;
- _errorhandler = _null_;
- _debughook = _null_;
- ci = NULL;
- INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);
-}
-
-void SQVM::Finalize()
-{
- _roottable = _null_;
- _lasterror = _null_;
- _errorhandler = _null_;
- _debughook = _null_;
- temp_reg = _null_;
- _callstackdata.resize(0);
- SQInteger size=_stack.size();
- for(SQInteger i=0;i<size;i++)
- _stack[i]=_null_;
-}
-
-SQVM::~SQVM()
-{
- Finalize();
- //sq_free(_callsstack,_alloccallsstacksize*sizeof(CallInfo));
- REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
-}
-
-bool SQVM::ArithMetaMethod(SQInteger op,const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &dest)
-{
- SQMetaMethod mm;
- switch(op){
- case _SC('+'): mm=MT_ADD; break;
- case _SC('-'): mm=MT_SUB; break;
- case _SC('/'): mm=MT_DIV; break;
- case _SC('*'): mm=MT_MUL; break;
- case _SC('%'): mm=MT_MODULO; break;
- default: mm = MT_ADD; assert(0); break; //shutup compiler
- }
- if(is_delegable(o1) && _delegable(o1)->_delegate) {
- Push(o1);Push(o2);
- return CallMetaMethod(_delegable(o1),mm,2,dest);
- }
- return false;
-}
-
-bool SQVM::NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o)
-{
-
- switch(type(o)) {
- case OT_INTEGER:
- trg = -_integer(o);
- return true;
- case OT_FLOAT:
- trg = -_float(o);
- return true;
- case OT_TABLE:
- case OT_USERDATA:
- case OT_INSTANCE:
- if(_delegable(o)->_delegate) {
- Push(o);
- if(CallMetaMethod(_delegable(o), MT_UNM, 1, temp_reg)) {
- trg = temp_reg;
- return true;
- }
- }
- default:break; //shutup compiler
- }
- Raise_Error(_SC("attempt to negate a %s"), GetTypeName(o));
- return false;
-}
-
-#define _RET_SUCCEED(exp) { result = (exp); return true; }
-bool SQVM::ObjCmp(const SQObjectPtr &o1,const SQObjectPtr &o2,SQInteger &result)
-{
- if(type(o1)==type(o2)){
- if(_userpointer(o1)==_userpointer(o2))_RET_SUCCEED(0);
- SQObjectPtr res;
- switch(type(o1)){
- case OT_STRING:
- _RET_SUCCEED(scstrcmp(_stringval(o1),_stringval(o2)));
- case OT_INTEGER:
- _RET_SUCCEED(_integer(o1)-_integer(o2));
- case OT_FLOAT:
- _RET_SUCCEED((_float(o1)<_float(o2))?-1:1);
- case OT_TABLE:
- case OT_USERDATA:
- case OT_INSTANCE:
- if(_delegable(o1)->_delegate) {
- Push(o1);Push(o2);
- if(CallMetaMethod(_delegable(o1),MT_CMP,2,res)) break;
- }
- //continues through (no break needed)
- default:
- _RET_SUCCEED( _userpointer(o1) < _userpointer(o2)?-1:1 );
- }
- if(type(res)!=OT_INTEGER) { Raise_CompareError(o1,o2); return false; }
- _RET_SUCCEED(_integer(res));
-
- }
- else{
- if(sq_isnumeric(o1) && sq_isnumeric(o2)){
- if((type(o1)==OT_INTEGER) && (type(o2)==OT_FLOAT)) {
- if( _integer(o1)==_float(o2) ) { _RET_SUCCEED(0); }
- else if( _integer(o1)<_float(o2) ) { _RET_SUCCEED(-1); }
- _RET_SUCCEED(1);
- }
- else{
- if( _float(o1)==_integer(o2) ) { _RET_SUCCEED(0); }
- else if( _float(o1)<_integer(o2) ) { _RET_SUCCEED(-1); }
- _RET_SUCCEED(1);
- }
- }
- else if(type(o1)==OT_NULL) {_RET_SUCCEED(-1);}
- else if(type(o2)==OT_NULL) {_RET_SUCCEED(1);}
- else { Raise_CompareError(o1,o2); return false; }
-
- }
- assert(0);
- _RET_SUCCEED(0); //cannot happen
-}
-
-bool SQVM::CMP_OP(CmpOP op, const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &res)
-{
- SQInteger r;
- if(ObjCmp(o1,o2,r)) {
- switch(op) {
- case CMP_G: res = (r > 0)?_true_:_false_; return true;
- case CMP_GE: res = (r >= 0)?_true_:_false_; return true;
- case CMP_L: res = (r < 0)?_true_:_false_; return true;
- case CMP_LE: res = (r <= 0)?_true_:_false_; return true;
-
- }
- assert(0);
- }
- return false;
-}
-
-void SQVM::ToString(const SQObjectPtr &o,SQObjectPtr &res)
-{
- switch(type(o)) {
- case OT_STRING:
- res = o;
- return;
- case OT_FLOAT:
- scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)),_SC("%g"),_float(o));
- break;
- case OT_INTEGER:
- scsprintf(_sp(rsl(NUMBER_MAX_CHAR+1)),_SC("%d"),_integer(o));
- break;
- case OT_BOOL:
- scsprintf(_sp(rsl(6)),_integer(o)?_SC("true"):_SC("false"));
- break;
- case OT_TABLE:
- case OT_USERDATA:
- case OT_INSTANCE:
- if(_delegable(o)->_delegate) {
- Push(o);
- if(CallMetaMethod(_delegable(o),MT_TOSTRING,1,res)) {
- if(type(res) == OT_STRING)
- return;
- //else keeps going to the default
- }
- }
- default:
- scsprintf(_sp(rsl(sizeof(void*)+20)),_SC("(%s : 0x%p)"),GetTypeName(o),(void*)_rawval(o));
- }
- res = SQString::Create(_ss(this),_spval);
-}
-
-
-bool SQVM::StringCat(const SQObjectPtr &str,const SQObjectPtr &obj,SQObjectPtr &dest)
-{
- SQObjectPtr a, b;
- ToString(str, a);
- ToString(obj, b);
- SQInteger l = _string(a)->_len , ol = _string(b)->_len;
- SQChar *s = _sp(rsl(l + ol + 1));
- memcpy(s, _stringval(a), rsl(l));
- memcpy(s + l, _stringval(b), rsl(ol));
- dest = SQString::Create(_ss(this), _spval, l + ol);
- return true;
-}
-
-void SQVM::TypeOf(const SQObjectPtr &obj1,SQObjectPtr &dest)
-{
- if(is_delegable(obj1) && _delegable(obj1)->_delegate) {
- Push(obj1);
- if(CallMetaMethod(_delegable(obj1),MT_TYPEOF,1,dest))
- return;
- }
- dest = SQString::Create(_ss(this),GetTypeName(obj1));
-}
-
-bool SQVM::Init(SQVM *friendvm, SQInteger stacksize)
-{
- _stack.resize(stacksize);
- _alloccallsstacksize = 4;
- _callstackdata.resize(_alloccallsstacksize);
- _callsstacksize = 0;
- _callsstack = &_callstackdata[0];
- _stackbase = 0;
- _top = 0;
- if(!friendvm)
- _roottable = SQTable::Create(_ss(this), 0);
- else {
- _roottable = friendvm->_roottable;
- _errorhandler = friendvm->_errorhandler;
- _debughook = friendvm->_debughook;
- }
-
- sq_base_register(this);
- return true;
-}
-
-extern SQInstructionDesc g_InstrDesc[];
-
-bool SQVM::StartCall(SQClosure *closure,SQInteger target,SQInteger args,SQInteger stackbase,bool tailcall)
-{
- SQFunctionProto *func = _funcproto(closure->_function);
-
- const SQInteger paramssize = func->_nparameters;
- const SQInteger newtop = stackbase + func->_stacksize;
- SQInteger nargs = args;
- if (paramssize != nargs) {
- SQInteger ndef = func->_ndefaultparams;
- if(ndef && nargs < paramssize) {
- SQInteger diff = paramssize - nargs;
- for(SQInteger n = ndef - diff; n < ndef; n++) {
- _stack._vals[stackbase + (nargs++)] = closure->_defaultparams[n];
- }
- }
- else if(func->_varparams)
- {
- if (nargs < paramssize) {
- Raise_Error(_SC("wrong number of parameters"));
- return false;
- }
- for(SQInteger n = 0; n < nargs - paramssize; n++) {
- _vargsstack.push_back(_stack._vals[stackbase+paramssize+n]);
- _stack._vals[stackbase+paramssize+n] = _null_;
- }
- }
- else {
- Raise_Error(_SC("wrong number of parameters"));
- return false;
- }
- }
-
- if(type(closure->_env) == OT_WEAKREF) {
- _stack._vals[stackbase] = _weakref(closure->_env)->_obj;
- }
-
- if (!tailcall) {
- CallInfo lc;
- lc._generator = NULL;
- lc._etraps = 0;
- lc._prevstkbase = (SQInt32) ( stackbase - _stackbase );
- lc._target = (SQInt32) target;
- lc._prevtop = (SQInt32) (_top - _stackbase);
- lc._ncalls = 1;
- lc._root = SQFalse;
- PUSH_CALLINFO(this, lc);
- }
- else {
- ci->_ncalls++;
- }
- ci->_vargs.size = (SQInt32)(nargs - paramssize);
- ci->_vargs.base = (SQInt32)(_vargsstack.size()-(ci->_vargs.size));
- ci->_closure = closure;
- ci->_literals = func->_literals;
- ci->_ip = func->_instructions;
- //grows the stack if needed
- if (((SQUnsignedInteger)newtop + (func->_stacksize<<1)) > _stack.size()) {
- _stack.resize(_stack.size() + (func->_stacksize<<1));
- }
-
- _top = newtop;
- _stackbase = stackbase;
- if (type(_debughook) != OT_NULL && _rawval(_debughook) != _rawval(ci->_closure))
- CallDebugHook(_SC('c'));
- return true;
-}
-
-bool SQVM::Return(SQInteger _arg0, SQInteger _arg1, SQObjectPtr &retval)
-{
- if (type(_debughook) != OT_NULL && _rawval(_debughook) != _rawval(ci->_closure))
- for(SQInteger i=0;i<ci->_ncalls;i++)
- CallDebugHook(_SC('r'));
-
- SQBool broot = ci->_root;
- SQInteger last_top = _top;
- SQInteger target = ci->_target;
- SQInteger oldstackbase = _stackbase;
- _stackbase -= ci->_prevstkbase;
- _top = _stackbase + ci->_prevtop;
- if(ci->_vargs.size) PopVarArgs(ci->_vargs);
- POP_CALLINFO(this);
- if (broot) {
- if (_arg0 != MAX_FUNC_STACKSIZE) retval = _stack._vals[oldstackbase+_arg1];
- else retval = _null_;
- }
- else {
- if(target != -1) { //-1 is when a class contructor ret value has to be ignored
- if (_arg0 != MAX_FUNC_STACKSIZE)
- STK(target) = _stack._vals[oldstackbase+_arg1];
- else
- STK(target) = _null_;
- }
- }
-
- CLEARSTACK(last_top);
- assert(oldstackbase >= _stackbase);
- return broot?true:false;
-}
-
-#define _RET_ON_FAIL(exp) { if(!exp) return false; }
-
-bool SQVM::LOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr)
-{
- _RET_ON_FAIL(ARITH_OP( op , target, a, incr));
- a = target;
- return true;
-}
-
-bool SQVM::PLOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr)
-{
- SQObjectPtr trg;
- _RET_ON_FAIL(ARITH_OP( op , trg, a, incr));
- target = a;
- a = trg;
- return true;
-}
-
-bool SQVM::DerefInc(SQInteger op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix)
-{
- SQObjectPtr tmp, tself = self, tkey = key;
- if (!Get(tself, tkey, tmp, false, true)) { Raise_IdxError(tkey); return false; }
- _RET_ON_FAIL(ARITH_OP( op , target, tmp, incr))
- Set(tself, tkey, target,true);
- if (postfix) target = tmp;
- return true;
-}
-
-#define arg0 (_i_._arg0)
-#define arg1 (_i_._arg1)
-#define sarg1 (*((SQInt32 *)&_i_._arg1))
-#define arg2 (_i_._arg2)
-#define arg3 (_i_._arg3)
-#define sarg3 ((SQInteger)*((signed char *)&_i_._arg3))
-
-SQRESULT SQVM::Suspend()
-{
- if (_suspended)
- return sq_throwerror(this, _SC("cannot suspend an already suspended vm"));
- if (_nnativecalls!=2)
- return sq_throwerror(this, _SC("cannot suspend through native calls/metamethods"));
- return SQ_SUSPEND_FLAG;
-}
-
-void SQVM::PopVarArgs(VarArgs &vargs)
-{
- for(SQInteger n = 0; n< vargs.size; n++)
- _vargsstack.pop_back();
-}
-
-#define _FINISH(howmuchtojump) {jump = howmuchtojump; return true; }
-bool SQVM::FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr
-&o3,SQObjectPtr &o4,SQInteger arg_2,int exitpos,int &jump)
-{
- SQInteger nrefidx;
- switch(type(o1)) {
- case OT_TABLE:
- if((nrefidx = _table(o1)->Next(false,o4, o2, o3)) == -1) _FINISH(exitpos);
- o4 = (SQInteger)nrefidx; _FINISH(1);
- case OT_ARRAY:
- if((nrefidx = _array(o1)->Next(o4, o2, o3)) == -1) _FINISH(exitpos);
- o4 = (SQInteger) nrefidx; _FINISH(1);
- case OT_STRING:
- if((nrefidx = _string(o1)->Next(o4, o2, o3)) == -1)_FINISH(exitpos);
- o4 = (SQInteger)nrefidx; _FINISH(1);
- case OT_CLASS:
- if((nrefidx = _class(o1)->Next(o4, o2, o3)) == -1)_FINISH(exitpos);
- o4 = (SQInteger)nrefidx; _FINISH(1);
- case OT_USERDATA:
- case OT_INSTANCE:
- if(_delegable(o1)->_delegate) {
- SQObjectPtr itr;
- Push(o1);
- Push(o4);
- if(CallMetaMethod(_delegable(o1), MT_NEXTI, 2, itr)){
- o4 = o2 = itr;
- if(type(itr) == OT_NULL) _FINISH(exitpos);
- if(!Get(o1, itr, o3, false,false)) {
- Raise_Error(_SC("_nexti returned an invalid idx"));
- return false;
- }
- _FINISH(1);
- }
- Raise_Error(_SC("_nexti failed"));
- return false;
- }
- break;
- case OT_GENERATOR:
- if(_generator(o1)->_state == SQGenerator::eDead) _FINISH(exitpos);
- if(_generator(o1)->_state == SQGenerator::eSuspended) {
- SQInteger idx = 0;
- if(type(o4) == OT_INTEGER) {
- idx = _integer(o4) + 1;
- }
- o2 = idx;
- o4 = idx;
- _generator(o1)->Resume(this, arg_2+1);
- _FINISH(0);
- }
- default:
- Raise_Error(_SC("cannot iterate %s"), GetTypeName(o1));
- }
- return false; //cannot be hit(just to avoid warnings)
-}
-
-bool SQVM::DELEGATE_OP(SQObjectPtr &trg,SQObjectPtr &o1,SQObjectPtr &o2)
-{
- if(type(o1) != OT_TABLE) { Raise_Error(_SC("delegating a '%s'"), GetTypeName(o1)); return false; }
- switch(type(o2)) {
- case OT_TABLE:
- if(!_table(o1)->SetDelegate(_table(o2))){
- Raise_Error(_SC("delegate cycle detected"));
- return false;
- }
- break;
- case OT_NULL:
- _table(o1)->SetDelegate(NULL);
- break;
- default:
- Raise_Error(_SC("using '%s' as delegate"), GetTypeName(o2));
- return false;
- break;
- }
- trg = o1;
- return true;
-}
-#define COND_LITERAL (arg3!=0?ci->_literals[arg1]:STK(arg1))
-
-#define _GUARD(exp) { if(!exp) { Raise_Error(_lasterror); SQ_THROW();} }
-
-#define SQ_THROW() { goto exception_trap; }
-
-bool SQVM::CLOSURE_OP(SQObjectPtr &target, SQFunctionProto *func)
-{
- SQInteger nouters;
- SQClosure *closure = SQClosure::Create(_ss(this), func);
- if((nouters = func->_noutervalues)) {
- closure->_outervalues.reserve(nouters);
- for(SQInteger i = 0; i<nouters; i++) {
- SQOuterVar &v = func->_outervalues[i];
- switch(v._type){
- case otSYMBOL:
- closure->_outervalues.push_back(_null_);
- if(!Get(_stack._vals[_stackbase]/*STK(0)*/, v._src, closure->_outervalues.top(), false,true))
- {Raise_IdxError(v._src); return false; }
- break;
- case otLOCAL:
- closure->_outervalues.push_back(_stack._vals[_stackbase+_integer(v._src)]);
- break;
- case otOUTER:
- closure->_outervalues.push_back(_closure(ci->_closure)->_outervalues[_integer(v._src)]);
- break;
- }
- }
- }
- SQInteger ndefparams;
- if((ndefparams = func->_ndefaultparams)) {
- closure->_defaultparams.reserve(ndefparams);
- for(SQInteger i = 0; i < ndefparams; i++) {
- SQInteger spos = func->_defaultparams[i];
- closure->_defaultparams.push_back(_stack._vals[_stackbase + spos]);
- }
- }
- target = closure;
- return true;
-
-}
-
-bool SQVM::GETVARGV_OP(SQObjectPtr &target,SQObjectPtr &index,CallInfo *ci)
-{
- if(ci->_vargs.size == 0) {
- Raise_Error(_SC("the function doesn't have var args"));
- return false;
- }
- if(!sq_isnumeric(index)){
- Raise_Error(_SC("indexing 'vargv' with %s"),GetTypeName(index));
- return false;
- }
- SQInteger idx = tointeger(index);
- if(idx < 0 || idx >= ci->_vargs.size){ Raise_Error(_SC("vargv index out of range")); return false; }
- target = _vargsstack[ci->_vargs.base+idx];
- return true;
-}
-
-bool SQVM::CLASS_OP(SQObjectPtr &target,SQInteger baseclass,SQInteger attributes)
-{
- SQClass *base = NULL;
- SQObjectPtr attrs;
- if(baseclass != -1) {
- if(type(_stack._vals[_stackbase+baseclass]) != OT_CLASS) { Raise_Error(_SC("trying to inherit from a %s"),GetTypeName(_stack._vals[_stackbase+baseclass])); return false; }
- base = _class(_stack._vals[_stackbase + baseclass]);
- }
- if(attributes != MAX_FUNC_STACKSIZE) {
- attrs = _stack._vals[_stackbase+attributes];
- }
- target = SQClass::Create(_ss(this),base);
- if(type(_class(target)->_metamethods[MT_INHERITED]) != OT_NULL) {
- int nparams = 2;
- SQObjectPtr ret;
- Push(target); Push(attrs);
- Call(_class(target)->_metamethods[MT_INHERITED],nparams,_top - nparams, ret, false);
- Pop(nparams);
- }
- _class(target)->_attributes = attrs;
- return true;
-}
-
-
-
-bool SQVM::IsEqual(SQObjectPtr &o1,SQObjectPtr &o2,bool &res)
-{
- if(type(o1) == type(o2)) {
- res = ((_userpointer(o1) == _userpointer(o2)?true:false));
- }
- else {
- if(sq_isnumeric(o1) && sq_isnumeric(o2)) {
- SQInteger cmpres;
- if(!ObjCmp(o1, o2,cmpres)) return false;
- res = (cmpres == 0);
- }
- else {
- res = false;
- }
- }
- return true;
-}
-
-bool SQVM::IsFalse(SQObjectPtr &o)
-{
- if((type(o) & SQOBJECT_CANBEFALSE) && ( (type(o) == OT_FLOAT) && (_float(o) == SQFloat(0.0)) )
- || (_integer(o) == 0) ) { //OT_NULL|OT_INTEGER|OT_BOOL
- return true;
- }
- return false;
-}
-
-bool SQVM::GETPARENT_OP(SQObjectPtr &o,SQObjectPtr &target)
-{
- switch(type(o)) {
- case OT_TABLE: target = _table(o)->_delegate?SQObjectPtr(_table(o)->_delegate):_null_;
- break;
- case OT_CLASS: target = _class(o)->_base?_class(o)->_base:_null_;
- break;
- default:
- Raise_Error(_SC("the %s type doesn't have a parent slot"), GetTypeName(o));
- return false;
- }
- return true;
-}
-
-bool SQVM::Execute(SQObjectPtr &closure, SQInteger target, SQInteger nargs, SQInteger stackbase,SQObjectPtr &outres, SQBool raiseerror,ExecutionType et)
-{
- if ((_nnativecalls + 1) > MAX_NATIVE_CALLS) { Raise_Error(_SC("Native stack overflow")); return false; }
- _nnativecalls++;
- AutoDec ad(&_nnativecalls);
- SQInteger traps = 0;
- //temp_reg vars for OP_CALL
- SQInteger ct_target;
- SQInteger ct_stackbase;
- bool ct_tailcall;
-
- switch(et) {
- case ET_CALL: {
- SQInteger last_top = _top;
- temp_reg = closure;
- if(!StartCall(_closure(temp_reg), _top - nargs, nargs, stackbase, false)) {
- //call the handler if there are no calls in the stack, if not relies on the previous node
- if(ci == NULL) CallErrorHandler(_lasterror);
- return false;
- }
- if (_funcproto(_closure(temp_reg)->_function)->_bgenerator) {
- SQFunctionProto *f = _funcproto(_closure(temp_reg)->_function);
- SQGenerator *gen = SQGenerator::Create(_ss(this), _closure(temp_reg));
- _GUARD(gen->Yield(this));
- Return(1, ci->_target, temp_reg);
- outres = gen;
- CLEARSTACK(last_top);
- return true;
- }
- ci->_root = SQTrue;
- }
- break;
- case ET_RESUME_GENERATOR: _generator(closure)->Resume(this, target); ci->_root = SQTrue; traps += ci->_etraps; break;
- case ET_RESUME_VM:
- case ET_RESUME_THROW_VM:
- traps = _suspended_traps;
- ci->_root = _suspended_root;
- ci->_vargs = _suspend_varargs;
- _suspended = SQFalse;
- if(et == ET_RESUME_THROW_VM) { SQ_THROW(); }
- break;
- }
-
-exception_restore:
- //
- {
- for(;;)
- {
- const SQInstruction &_i_ = *ci->_ip++;
- //dumpstack(_stackbase);
- //scprintf("\n[%d] %s %d %d %d %d\n",ci->_ip-ci->_iv->_vals,g_InstrDesc[_i_.op].name,arg0,arg1,arg2,arg3);
- switch(_i_.op)
- {
- case _OP_LINE:
- if(type(_debughook) != OT_NULL && _rawval(_debughook) != _rawval(ci->_closure))
- CallDebugHook(_SC('l'),arg1);
- continue;
- case _OP_LOAD: TARGET = ci->_literals[arg1]; continue;
- case _OP_LOADINT: TARGET = (SQInteger)arg1; continue;
- case _OP_LOADFLOAT: TARGET = *((SQFloat *)&arg1); continue;
- case _OP_DLOAD: TARGET = ci->_literals[arg1]; STK(arg2) = ci->_literals[arg3];continue;
- case _OP_TAILCALL:
- temp_reg = STK(arg1);
- if (type(temp_reg) == OT_CLOSURE && !_funcproto(_closure(temp_reg)->_function)->_bgenerator){
- ct_tailcall = true;
- if(ci->_vargs.size) PopVarArgs(ci->_vargs);
- for (SQInteger i = 0; i < arg3; i++) STK(i) = STK(arg2 + i);
- ct_target = ci->_target;
- ct_stackbase = _stackbase;
- goto common_call;
- }
- case _OP_CALL: {
- ct_tailcall = false;
- ct_target = arg0;
- temp_reg = STK(arg1);
- ct_stackbase = _stackbase+arg2;
-
-common_call:
- SQObjectPtr clo = temp_reg;
- SQInteger last_top = _top;
- switch (type(clo)) {
- case OT_CLOSURE:{
- _GUARD(StartCall(_closure(clo), ct_target, arg3, ct_stackbase, ct_tailcall));
- if (_funcproto(_closure(clo)->_function)->_bgenerator) {
- SQGenerator *gen = SQGenerator::Create(_ss(this), _closure(clo));
- _GUARD(gen->Yield(this));
- Return(1, ct_target, clo);
- STK(ct_target) = gen;
- CLEARSTACK(last_top);
- continue;
- }
- }
- continue;
- case OT_NATIVECLOSURE: {
- bool suspend;
- _GUARD(CallNative(_nativeclosure(clo), arg3, ct_stackbase, clo,suspend));
- if(suspend){
- _suspended = SQTrue;
- _suspended_target = ct_target;
- _suspended_root = ci->_root;
- _suspended_traps = traps;
- _suspend_varargs = ci->_vargs;
- outres = clo;
- return true;
- }
- if(ct_target != -1) { //skip return value for constructors
- STK(ct_target) = clo;
- }
- }
- continue;
- case OT_CLASS:{
- SQObjectPtr inst;
- _GUARD(CreateClassInstance(_class(clo),inst,temp_reg));
- STK(ct_target) = inst;
- ct_target = -1; //fakes return value target so that is not overwritten by the constructor
- if(type(temp_reg) != OT_NULL) {
- _stack._vals[ct_stackbase] = inst;
- goto common_call; //hard core spaghetti code(reissues the OP_CALL to invoke the constructor)
- }
- }
- break;
- case OT_TABLE:
- case OT_USERDATA:
- case OT_INSTANCE:
- {
- Push(clo);
- for (SQInteger i = 0; i < arg3; i++) Push(STK(arg2 + i));
- if (_delegable(clo) && CallMetaMethod(_delegable(clo), MT_CALL, arg3+1, clo)){
- STK(ct_target) = clo;
- break;
- }
- Raise_Error(_SC("attempt to call '%s'"), GetTypeName(clo));
- SQ_THROW();
- }
- default:
- Raise_Error(_SC("attempt to call '%s'"), GetTypeName(clo));
- SQ_THROW();
- }
- }
- continue;
- case _OP_PREPCALL:
- case _OP_PREPCALLK:
- {
- SQObjectPtr &key = _i_.op == _OP_PREPCALLK?(ci->_literals)[arg1]:STK(arg1);
- SQObjectPtr &o = STK(arg2);
- if (!Get(o, key, temp_reg,false,true)) {
- if(type(o) == OT_CLASS) { //hack?
- if(_class_ddel->Get(key,temp_reg)) {
- STK(arg3) = o;
- TARGET = temp_reg;
- continue;
- }
- }
- { Raise_IdxError(key); SQ_THROW();}
- }
-
- STK(arg3) = type(o) == OT_CLASS?STK(0):o;
- TARGET = temp_reg;
- }
- continue;
- case _OP_GETK:
- if (!Get(STK(arg2), ci->_literals[arg1], temp_reg, false,true)) { Raise_IdxError(ci->_literals[arg1]); SQ_THROW();}
- TARGET = temp_reg;
- continue;
- case _OP_MOVE: TARGET = STK(arg1); continue;
- case _OP_NEWSLOT:
- _GUARD(NewSlot(STK(arg1), STK(arg2), STK(arg3),false));
- if(arg0 != arg3) TARGET = STK(arg3);
- continue;
- case _OP_DELETE: _GUARD(DeleteSlot(STK(arg1), STK(arg2), TARGET)); continue;
- case _OP_SET:
- if (!Set(STK(arg1), STK(arg2), STK(arg3),true)) { Raise_IdxError(STK(arg2)); SQ_THROW(); }
- if (arg0 != arg3) TARGET = STK(arg3);
- continue;
- case _OP_GET:
- if (!Get(STK(arg1), STK(arg2), temp_reg, false,true)) { Raise_IdxError(STK(arg2)); SQ_THROW(); }
- TARGET = temp_reg;
- continue;
- case _OP_EQ:{
- bool res;
- if(!IsEqual(STK(arg2),COND_LITERAL,res)) { SQ_THROW(); }
- TARGET = res?_true_:_false_;
- }continue;
- case _OP_NE:{
- bool res;
- if(!IsEqual(STK(arg2),COND_LITERAL,res)) { SQ_THROW(); }
- TARGET = (!res)?_true_:_false_;
- } continue;
- case _OP_ARITH: _GUARD(ARITH_OP( arg3 , temp_reg, STK(arg2), STK(arg1))); TARGET = temp_reg; continue;
- case _OP_BITW: _GUARD(BW_OP( arg3,TARGET,STK(arg2),STK(arg1))); continue;
- case _OP_RETURN:
- if(ci->_generator) {
- ci->_generator->Kill();
- }
- if(Return(arg0, arg1, temp_reg)){
- assert(traps==0);
- outres = temp_reg;
- return true;
- }
- continue;
- case _OP_LOADNULLS:{ for(SQInt32 n=0; n < arg1; n++) STK(arg0+n) = _null_; }continue;
- case _OP_LOADROOTTABLE: TARGET = _roottable; continue;
- case _OP_LOADBOOL: TARGET = arg1?_true_:_false_; continue;
- case _OP_DMOVE: STK(arg0) = STK(arg1); STK(arg2) = STK(arg3); continue;
- case _OP_JMP: ci->_ip += (sarg1); continue;
- case _OP_JNZ: if(!IsFalse(STK(arg0))) ci->_ip+=(sarg1); continue;
- case _OP_JZ: if(IsFalse(STK(arg0))) ci->_ip+=(sarg1); continue;
- case _OP_LOADFREEVAR: TARGET = _closure(ci->_closure)->_outervalues[arg1]; continue;
- case _OP_VARGC: TARGET = SQInteger(ci->_vargs.size); continue;
- case _OP_GETVARGV:
- if(!GETVARGV_OP(TARGET,STK(arg1),ci)) { SQ_THROW(); }
- continue;
- case _OP_NEWTABLE: TARGET = SQTable::Create(_ss(this), arg1); continue;
- case _OP_NEWARRAY: TARGET = SQArray::Create(_ss(this), 0); _array(TARGET)->Reserve(arg1); continue;
- case _OP_APPENDARRAY: _array(STK(arg0))->Append(COND_LITERAL); continue;
- case _OP_GETPARENT: _GUARD(GETPARENT_OP(STK(arg1),TARGET)); continue;
- case _OP_COMPARITH: _GUARD(DerefInc(arg3, TARGET, STK((((SQUnsignedInteger)arg1&0xFFFF0000)>>16)), STK(arg2), STK(arg1&0x0000FFFF), false)); continue;
- case _OP_COMPARITHL: _GUARD(LOCAL_INC(arg3, TARGET, STK(arg1), STK(arg2))); continue;
- case _OP_INC: {SQObjectPtr o(sarg3); _GUARD(DerefInc('+',TARGET, STK(arg1), STK(arg2), o, false));} continue;
- case _OP_INCL: {SQObjectPtr o(sarg3); _GUARD(LOCAL_INC('+',TARGET, STK(arg1), o));} continue;
- case _OP_PINC: {SQObjectPtr o(sarg3); _GUARD(DerefInc('+',TARGET, STK(arg1), STK(arg2), o, true));} continue;
- case _OP_PINCL: {SQObjectPtr o(sarg3); _GUARD(PLOCAL_INC('+',TARGET, STK(arg1), o));} continue;
- case _OP_CMP: _GUARD(CMP_OP((CmpOP)arg3,STK(arg2),STK(arg1),TARGET)) continue;
- case _OP_EXISTS: TARGET = Get(STK(arg1), STK(arg2), temp_reg, true,false)?_true_:_false_;continue;
- case _OP_INSTANCEOF:
- if(type(STK(arg1)) != OT_CLASS || type(STK(arg2)) != OT_INSTANCE)
- {Raise_Error(_SC("cannot apply instanceof between a %s and a %s"),GetTypeName(STK(arg1)),GetTypeName(STK(arg2))); SQ_THROW();}
- TARGET = _instance(STK(arg2))->InstanceOf(_class(STK(arg1)))?_true_:_false_;
- continue;
- case _OP_AND:
- if(IsFalse(STK(arg2))) {
- TARGET = STK(arg2);
- ci->_ip += (sarg1);
- }
- continue;
- case _OP_OR:
- if(!IsFalse(STK(arg2))) {
- TARGET = STK(arg2);
- ci->_ip += (sarg1);
- }
- continue;
- case _OP_NEG: _GUARD(NEG_OP(TARGET,STK(arg1))); continue;
- case _OP_NOT: TARGET = (IsFalse(STK(arg1))?_true_:_false_); continue;
- case _OP_BWNOT:
- if(type(STK(arg1)) == OT_INTEGER) {
- SQInteger t = _integer(STK(arg1));
- TARGET = SQInteger(~t);
- continue;
- }
- Raise_Error(_SC("attempt to perform a bitwise op on a %s"), GetTypeName(STK(arg1)));
- SQ_THROW();
- case _OP_CLOSURE: {
- SQClosure *c = ci->_closure._unVal.pClosure;
- SQFunctionProto *fp = c->_function._unVal.pFunctionProto;
- if(!CLOSURE_OP(TARGET,fp->_functions[arg1]._unVal.pFunctionProto)) { SQ_THROW(); }
- continue;
- }
- case _OP_YIELD:{
- if(ci->_generator) {
- if(sarg1 != MAX_FUNC_STACKSIZE) temp_reg = STK(arg1);
- _GUARD(ci->_generator->Yield(this));
- traps -= ci->_etraps;
- if(sarg1 != MAX_FUNC_STACKSIZE) STK(arg1) = temp_reg;
- }
- else { Raise_Error(_SC("trying to yield a '%s',only genenerator can be yielded"), GetTypeName(ci->_generator)); SQ_THROW();}
- if(Return(arg0, arg1, temp_reg)){
- assert(traps == 0);
- outres = temp_reg;
- return true;
- }
-
- }
- continue;
- case _OP_RESUME:
- if(type(STK(arg1)) != OT_GENERATOR){ Raise_Error(_SC("trying to resume a '%s',only genenerator can be resumed"), GetTypeName(STK(arg1))); SQ_THROW();}
- _GUARD(_generator(STK(arg1))->Resume(this, arg0));
- traps += ci->_etraps;
- continue;
- case _OP_FOREACH:{ int tojump;
- _GUARD(FOREACH_OP(STK(arg0),STK(arg2),STK(arg2+1),STK(arg2+2),arg2,sarg1,tojump));
- ci->_ip += tojump; }
- continue;
- case _OP_POSTFOREACH:
- assert(type(STK(arg0)) == OT_GENERATOR);
- if(_generator(STK(arg0))->_state == SQGenerator::eDead)
- ci->_ip += (sarg1 - 1);
- continue;
- case _OP_DELEGATE: _GUARD(DELEGATE_OP(TARGET,STK(arg1),STK(arg2))); continue;
- case _OP_CLONE:
- if(!Clone(STK(arg1), TARGET))
- { Raise_Error(_SC("cloning a %s"), GetTypeName(STK(arg1))); SQ_THROW();}
- continue;
- case _OP_TYPEOF: TypeOf(STK(arg1), TARGET); continue;
- case _OP_PUSHTRAP:{
- SQInstruction *_iv = _funcproto(_closure(ci->_closure)->_function)->_instructions;
- _etraps.push_back(SQExceptionTrap(_top,_stackbase, &_iv[(ci->_ip-_iv)+arg1], arg0)); traps++;
- ci->_etraps++;
- }
- continue;
- case _OP_POPTRAP: {
- for(SQInteger i = 0; i < arg0; i++) {
- _etraps.pop_back(); traps--;
- ci->_etraps--;
- }
- }
- continue;
- case _OP_THROW: Raise_Error(TARGET); SQ_THROW(); continue;
- case _OP_CLASS: _GUARD(CLASS_OP(TARGET,arg1,arg2)); continue;
- case _OP_NEWSLOTA:
- bool bstatic = (arg0&NEW_SLOT_STATIC_FLAG)?true:false;
- if(type(STK(arg1)) == OT_CLASS) {
- if(type(_class(STK(arg1))->_metamethods[MT_NEWMEMBER]) != OT_NULL ) {
- Push(STK(arg1)); Push(STK(arg2)); Push(STK(arg3));
- Push((arg0&NEW_SLOT_ATTRIBUTES_FLAG) ? STK(arg2-1) : _null_);
- int nparams = 4;
- if(Call(_class(STK(arg1))->_metamethods[MT_NEWMEMBER], nparams, _top - nparams, temp_reg,SQFalse)) {
- Pop(nparams);
- continue;
- }
- }
- }
- _GUARD(NewSlot(STK(arg1), STK(arg2), STK(arg3),bstatic));
- if((arg0&NEW_SLOT_ATTRIBUTES_FLAG)) {
- _class(STK(arg1))->SetAttributes(STK(arg2),STK(arg2-1));
- }
- continue;
- }
-
- }
- }
-exception_trap:
- {
- SQObjectPtr currerror = _lasterror;
-// dumpstack(_stackbase);
- SQInteger n = 0;
- SQInteger last_top = _top;
- if(ci) {
- if(_ss(this)->_notifyallexceptions) CallErrorHandler(currerror);
-
- if(traps) {
- do {
- if(ci->_etraps > 0) {
- SQExceptionTrap &et = _etraps.top();
- ci->_ip = et._ip;
- _top = et._stacksize;
- _stackbase = et._stackbase;
- _stack._vals[_stackbase+et._extarget] = currerror;
- _etraps.pop_back(); traps--; ci->_etraps--;
- CLEARSTACK(last_top);
- goto exception_restore;
- }
- //if is a native closure
- if(type(ci->_closure) != OT_CLOSURE && n)
- break;
- if(ci->_generator) ci->_generator->Kill();
- PopVarArgs(ci->_vargs);
- POP_CALLINFO(this);
- n++;
- } while(_callsstacksize);
- }
- else {
- //call the hook
- if(raiseerror && !_ss(this)->_notifyallexceptions)
- CallErrorHandler(currerror);
- }
- //remove call stack until a C function is found or the cstack is empty
- if(ci) do {
- SQBool exitafterthisone = ci->_root;
- if(ci->_generator) ci->_generator->Kill();
- _stackbase -= ci->_prevstkbase;
- _top = _stackbase + ci->_prevtop;
- PopVarArgs(ci->_vargs);
- POP_CALLINFO(this);
- if( (ci && type(ci->_closure) != OT_CLOSURE) || exitafterthisone) break;
- } while(_callsstacksize);
-
- CLEARSTACK(last_top);
- }
- _lasterror = currerror;
- return false;
- }
- assert(0);
-}
-
-bool SQVM::CreateClassInstance(SQClass *theclass, SQObjectPtr &inst, SQObjectPtr &constructor)
-{
- inst = theclass->CreateInstance();
- if(!theclass->Get(_ss(this)->_constructoridx,constructor)) {
- constructor = _null_;
- }
- return true;
-}
-
-void SQVM::CallErrorHandler(SQObjectPtr &error)
-{
- if(type(_errorhandler) != OT_NULL) {
- SQObjectPtr out;
- Push(_roottable); Push(error);
- Call(_errorhandler, 2, _top-2, out,SQFalse);
- Pop(2);
- }
-}
-
-void SQVM::CallDebugHook(SQInteger type,SQInteger forcedline)
-{
- SQObjectPtr temp_reg;
- SQInteger nparams=5;
- SQFunctionProto *func=_funcproto(_closure(ci->_closure)->_function);
- Push(_roottable); Push(type); Push(func->_sourcename); Push(forcedline?forcedline:func->GetLine(ci->_ip)); Push(func->_name);
- Call(_debughook,nparams,_top-nparams,temp_reg,SQFalse);
- Pop(nparams);
-}
-
-bool SQVM::CallNative(SQNativeClosure *nclosure,SQInteger nargs,SQInteger stackbase,SQObjectPtr &retval,bool &suspend)
-{
- if (_nnativecalls + 1 > MAX_NATIVE_CALLS) { Raise_Error(_SC("Native stack overflow")); return false; }
- SQInteger nparamscheck = nclosure->_nparamscheck;
- if(((nparamscheck > 0) && (nparamscheck != nargs))
- || ((nparamscheck < 0) && (nargs < (-nparamscheck)))) {
- Raise_Error(_SC("wrong number of parameters"));
- return false;
- }
-
- SQInteger tcs;
- if((tcs = nclosure->_typecheck.size())) {
- for(SQInteger i = 0; i < nargs && i < tcs; i++)
- if((nclosure->_typecheck._vals[i] != -1) && !(type(_stack._vals[stackbase+i]) & nclosure->_typecheck[i])) {
- Raise_ParamTypeError(i,nclosure->_typecheck._vals[i],type(_stack._vals[stackbase+i]));
- return false;
- }
- }
- _nnativecalls++;
- if ((_top + MIN_STACK_OVERHEAD) > (SQInteger)_stack.size()) {
- _stack.resize(_stack.size() + (MIN_STACK_OVERHEAD<<1));
- }
- SQInteger oldtop = _top;
- SQInteger oldstackbase = _stackbase;
- _top = stackbase + nargs;
- CallInfo lci;
- lci._closure = nclosure;
- lci._generator = NULL;
- lci._etraps = 0;
- lci._prevstkbase = (SQInt32) (stackbase - _stackbase);
- lci._ncalls = 1;
- lci._prevtop = (SQInt32) (oldtop - oldstackbase);
- PUSH_CALLINFO(this, lci);
- _stackbase = stackbase;
- //push free variables
- SQInteger outers = nclosure->_outervalues.size();
- for (SQInteger i = 0; i < outers; i++) {
- Push(nclosure->_outervalues[i]);
- }
-
- if(type(nclosure->_env) == OT_WEAKREF) {
- _stack[stackbase] = _weakref(nclosure->_env)->_obj;
- }
-
-
- SQInteger ret = (nclosure->_function)(this);
- _nnativecalls--;
- suspend = false;
- if( ret == SQ_SUSPEND_FLAG) suspend = true;
- else if (ret < 0) {
- _stackbase = oldstackbase;
- _top = oldtop;
- POP_CALLINFO(this);
- Raise_Error(_lasterror);
- return false;
- }
-
- if (ret != 0){ retval = TOP(); TOP().Null(); }
- else { retval = _null_; }
- _stackbase = oldstackbase;
- _top = oldtop;
- POP_CALLINFO(this);
- return true;
-}
-
-bool SQVM::Get(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest,bool raw, bool fetchroot)
-{
- switch(type(self)){
- case OT_TABLE:
- if(_table(self)->Get(key,dest))return true;
- break;
- case OT_ARRAY:
- if(sq_isnumeric(key)){
- return _array(self)->Get(tointeger(key),dest);
- }
- break;
- case OT_INSTANCE:
- if(_instance(self)->Get(key,dest)) return true;
- break;
- default:break; //shut up compiler
- }
- if(FallBackGet(self,key,dest,raw)) return true;
-
- if(fetchroot) {
- if(_rawval(STK(0)) == _rawval(self) &&
- type(STK(0)) == type(self)) {
- return _table(_roottable)->Get(key,dest);
- }
- }
- return false;
-}
-
-bool SQVM::FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest,bool raw)
-{
- switch(type(self)){
- case OT_CLASS:
- return _class(self)->Get(key,dest);
- break;
- case OT_TABLE:
- case OT_USERDATA:
- //delegation
- if(_delegable(self)->_delegate) {
- if(Get(SQObjectPtr(_delegable(self)->_delegate),key,dest,raw,false))
- return true;
- if(raw)return false;
- Push(self);Push(key);
- if(CallMetaMethod(_delegable(self),MT_GET,2,dest))
- return true;
- }
- if(type(self) == OT_TABLE) {
- if(raw) return false;
- return _table_ddel->Get(key,dest);
- }
- return false;
- break;
- case OT_ARRAY:
- if(raw)return false;
- return _array_ddel->Get(key,dest);
- case OT_STRING:
- if(sq_isnumeric(key)){
- SQInteger n=tointeger(key);
- if(abs((int)n)<_string(self)->_len){
- if(n<0)n=_string(self)->_len-n;
- dest=SQInteger(_stringval(self)[n]);
- return true;
- }
- return false;
- }
- else {
- if(raw)return false;
- return _string_ddel->Get(key,dest);
- }
- break;
- case OT_INSTANCE:
- if(raw)return false;
- Push(self);Push(key);
- if(!CallMetaMethod(_delegable(self),MT_GET,2,dest)) {
- return _instance_ddel->Get(key,dest);
- }
- return true;
- case OT_INTEGER:case OT_FLOAT:case OT_BOOL:
- if(raw)return false;
- return _number_ddel->Get(key,dest);
- case OT_GENERATOR:
- if(raw)return false;
- return _generator_ddel->Get(key,dest);
- case OT_CLOSURE: case OT_NATIVECLOSURE:
- if(raw)return false;
- return _closure_ddel->Get(key,dest);
- case OT_THREAD:
- if(raw)return false;
- return _thread_ddel->Get(key,dest);
- case OT_WEAKREF:
- if(raw)return false;
- return _weakref_ddel->Get(key,dest);
- default:return false;
- }
- return false;
-}
-
-bool SQVM::Set(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val,bool fetchroot)
-{
- switch(type(self)){
- case OT_TABLE:
- if(_table(self)->Set(key,val))
- return true;
- if(_table(self)->_delegate) {
- if(Set(_table(self)->_delegate,key,val,false)) {
- return true;
- }
- }
- //keeps going
- case OT_USERDATA:
- if(_delegable(self)->_delegate) {
- SQObjectPtr t;
- Push(self);Push(key);Push(val);
- if(CallMetaMethod(_delegable(self),MT_SET,3,t)) return true;
- }
- break;
- case OT_INSTANCE:{
- if(_instance(self)->Set(key,val))
- return true;
- SQObjectPtr t;
- Push(self);Push(key);Push(val);
- if(CallMetaMethod(_delegable(self),MT_SET,3,t)) return true;
- }
- break;
- case OT_ARRAY:
- if(!sq_isnumeric(key)) {Raise_Error(_SC("indexing %s with %s"),GetTypeName(self),GetTypeName(key)); return false; }
- return _array(self)->Set(tointeger(key),val);
- default:
- Raise_Error(_SC("trying to set '%s'"),GetTypeName(self));
- return false;
- }
- if(fetchroot) {
- if(_rawval(STK(0)) == _rawval(self) &&
- type(STK(0)) == type(self)) {
- return _table(_roottable)->Set(key,val);
- }
- }
- return false;
-}
-
-bool SQVM::Clone(const SQObjectPtr &self,SQObjectPtr &target)
-{
- SQObjectPtr temp_reg;
- SQObjectPtr newobj;
- switch(type(self)){
- case OT_TABLE:
- newobj = _table(self)->Clone();
- goto cloned_mt;
- case OT_INSTANCE:
- newobj = _instance(self)->Clone(_ss(this));
-cloned_mt:
- if(_delegable(newobj)->_delegate){
- Push(newobj);
- Push(self);
- CallMetaMethod(_delegable(newobj),MT_CLONED,2,temp_reg);
- }
- target = newobj;
- return true;
- case OT_ARRAY:
- target = _array(self)->Clone();
- return true;
- default: return false;
- }
-}
-
-bool SQVM::NewSlot(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr &val,bool bstatic)
-{
- if(type(key) == OT_NULL) { Raise_Error(_SC("null cannot be used as index")); return false; }
- switch(type(self)) {
- case OT_TABLE: {
- bool rawcall = true;
- if(_table(self)->_delegate) {
- SQObjectPtr res;
- if(!_table(self)->Get(key,res)) {
- Push(self);Push(key);Push(val);
- rawcall = !CallMetaMethod(_table(self),MT_NEWSLOT,3,res);
- }
- }
- if(rawcall) _table(self)->NewSlot(key,val); //cannot fail
-
- break;}
- case OT_INSTANCE: {
- SQObjectPtr res;
- Push(self);Push(key);Push(val);
- if(!CallMetaMethod(_instance(self),MT_NEWSLOT,3,res)) {
- Raise_Error(_SC("class instances do not support the new slot operator"));
- return false;
- }
- break;}
- case OT_CLASS:
- if(!_class(self)->NewSlot(_ss(this),key,val,bstatic)) {
- if(_class(self)->_locked) {
- Raise_Error(_SC("trying to modify a class that has already been instantiated"));
- return false;
- }
- else {
- SQObjectPtr oval = PrintObjVal(key);
- Raise_Error(_SC("the property '%s' already exists"),_stringval(oval));
- return false;
- }
- }
- break;
- default:
- Raise_Error(_SC("indexing %s with %s"),GetTypeName(self),GetTypeName(key));
- return false;
- break;
- }
- return true;
-}
-
-bool SQVM::DeleteSlot(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &res)
-{
- switch(type(self)) {
- case OT_TABLE:
- case OT_INSTANCE:
- case OT_USERDATA: {
- SQObjectPtr t;
- bool handled = false;
- if(_delegable(self)->_delegate) {
- Push(self);Push(key);
- handled = CallMetaMethod(_delegable(self),MT_DELSLOT,2,t);
- }
-
- if(!handled) {
- if(type(self) == OT_TABLE) {
- if(_table(self)->Get(key,t)) {
- _table(self)->Remove(key);
- }
- else {
- Raise_IdxError((SQObject &)key);
- return false;
- }
- }
- else {
- Raise_Error(_SC("cannot delete a slot from %s"),GetTypeName(self));
- return false;
- }
- }
- res = t;
- }
- break;
- default:
- Raise_Error(_SC("attempt to delete a slot from a %s"),GetTypeName(self));
- return false;
- }
- return true;
-}
-
-bool SQVM::Call(SQObjectPtr &closure,SQInteger nparams,SQInteger stackbase,SQObjectPtr &outres,SQBool raiseerror)
-{
-#ifdef _DEBUG
-SQInteger prevstackbase = _stackbase;
-#endif
- switch(type(closure)) {
- case OT_CLOSURE:
- return Execute(closure, _top - nparams, nparams, stackbase,outres,raiseerror);
- break;
- case OT_NATIVECLOSURE:{
- bool suspend;
- return CallNative(_nativeclosure(closure), nparams, stackbase, outres,suspend);
-
- }
- break;
- case OT_CLASS: {
- SQObjectPtr constr;
- SQObjectPtr temp;
- CreateClassInstance(_class(closure),outres,constr);
- if(type(constr) != OT_NULL) {
- _stack[stackbase] = outres;
- return Call(constr,nparams,stackbase,temp,raiseerror);
- }
- return true;
- }
- break;
- default:
- return false;
- }
-#ifdef _DEBUG
- if(!_suspended) {
- assert(_stackbase == prevstackbase);
- }
-#endif
- return true;
-}
-
-bool SQVM::CallMetaMethod(SQDelegable *del,SQMetaMethod mm,SQInteger nparams,SQObjectPtr &outres)
-{
- SQObjectPtr closure;
- if(del->GetMetaMethod(this, mm, closure)) {
- if(Call(closure, nparams, _top - nparams, outres, SQFalse)) {
- Pop(nparams);
- return true;
- }
- }
- Pop(nparams);
- return false;
-}
-
-void SQVM::Remove(SQInteger n) {
- n = (n >= 0)?n + _stackbase - 1:_top + n;
- for(SQInteger i = n; i < _top; i++){
- _stack[i] = _stack[i+1];
- }
- _stack[_top] = _null_;
- _top--;
-}
-
-void SQVM::Pop() {
- _stack[--_top] = _null_;
-}
-
-void SQVM::Pop(SQInteger n) {
- for(SQInteger i = 0; i < n; i++){
- _stack[--_top] = _null_;
- }
-}
-
-void SQVM::Push(const SQObjectPtr &o) { _stack[_top++] = o; }
-SQObjectPtr &SQVM::Top() { return _stack[_top-1]; }
-SQObjectPtr &SQVM::PopGet() { return _stack[--_top]; }
-SQObjectPtr &SQVM::GetUp(SQInteger n) { return _stack[_top+n]; }
-SQObjectPtr &SQVM::GetAt(SQInteger n) { return _stack[n]; }
-
-#ifdef _DEBUG_DUMP
-void SQVM::dumpstack(SQInteger stackbase,bool dumpall)
-{
- SQInteger size=dumpall?_stack.size():_top;
- SQInteger n=0;
- scprintf(_SC("\n>>>>stack dump<<<<\n"));
- CallInfo &ci=_callsstack[_callsstacksize-1];
- scprintf(_SC("IP: %p\n"),ci._ip);
- scprintf(_SC("prev stack base: %d\n"),ci._prevstkbase);
- scprintf(_SC("prev top: %d\n"),ci._prevtop);
- for(SQInteger i=0;i<size;i++){
- SQObjectPtr &obj=_stack[i];
- if(stackbase==i)scprintf(_SC(">"));else scprintf(_SC(" "));
- scprintf(_SC("[%d]:"),n);
- switch(type(obj)){
- case OT_FLOAT: scprintf(_SC("FLOAT %.3f"),_float(obj));break;
- case OT_INTEGER: scprintf(_SC("INTEGER %d"),_integer(obj));break;
- case OT_BOOL: scprintf(_SC("BOOL %s"),_integer(obj)?"true":"false");break;
- case OT_STRING: scprintf(_SC("STRING %s"),_stringval(obj));break;
- case OT_NULL: scprintf(_SC("NULL")); break;
- case OT_TABLE: scprintf(_SC("TABLE %p[%p]"),_table(obj),_table(obj)->_delegate);break;
- case OT_ARRAY: scprintf(_SC("ARRAY %p"),_array(obj));break;
- case OT_CLOSURE: scprintf(_SC("CLOSURE [%p]"),_closure(obj));break;
- case OT_NATIVECLOSURE: scprintf(_SC("NATIVECLOSURE"));break;
- case OT_USERDATA: scprintf(_SC("USERDATA %p[%p]"),_userdataval(obj),_userdata(obj)->_delegate);break;
- case OT_GENERATOR: scprintf(_SC("GENERATOR %p"),_generator(obj));break;
- case OT_THREAD: scprintf(_SC("THREAD [%p]"),_thread(obj));break;
- case OT_USERPOINTER: scprintf(_SC("USERPOINTER %p"),_userpointer(obj));break;
- case OT_CLASS: scprintf(_SC("CLASS %p"),_class(obj));break;
- case OT_INSTANCE: scprintf(_SC("INSTANCE %p"),_instance(obj));break;
- case OT_WEAKREF: scprintf(_SC("WEAKERF %p"),_weakref(obj));break;
- default:
- assert(0);
- break;
- };
- scprintf(_SC("\n"));
- ++n;
- }
-}
-
-
-
-#endif
+++ /dev/null
-/* see copyright notice in squirrel.h */
-#ifndef _SQVM_H_
-#define _SQVM_H_
-
-#include "sqopcodes.h"
-#include "sqobject.h"
-#define MAX_NATIVE_CALLS 100
-#define MIN_STACK_OVERHEAD 10
-
-#define SQ_SUSPEND_FLAG -666
-//base lib
-void sq_base_register(HSQUIRRELVM v);
-
-struct SQExceptionTrap{
- SQExceptionTrap() {}
- SQExceptionTrap(SQInteger ss, SQInteger stackbase,SQInstruction *ip, SQInteger ex_target){ _stacksize = ss; _stackbase = stackbase; _ip = ip; _extarget = ex_target;}
- SQExceptionTrap(const SQExceptionTrap &et) { (*this) = et; }
- SQInteger _stackbase;
- SQInteger _stacksize;
- SQInstruction *_ip;
- SQInteger _extarget;
-};
-
-#define _INLINE
-
-#define STK(a) _stack._vals[_stackbase+(a)]
-#define TARGET _stack._vals[_stackbase+arg0]
-
-typedef sqvector<SQExceptionTrap> ExceptionsTraps;
-
-struct SQVM : public CHAINABLE_OBJ
-{
- struct VarArgs {
- VarArgs() { size = 0; base = 0; }
- unsigned short size;
- unsigned short base;
- };
-
- struct CallInfo{
- //CallInfo() { _generator._type = OT_NULL;}
- SQInstruction *_ip;
- SQObjectPtr *_literals;
- SQObjectPtr _closure;
- SQGenerator *_generator;
- SQInt32 _etraps;
- SQInt32 _prevstkbase;
- SQInt32 _prevtop;
- SQInt32 _target;
- SQInt32 _ncalls;
- SQBool _root;
- VarArgs _vargs;
- };
-
-typedef sqvector<CallInfo> CallInfoVec;
-public:
- enum ExecutionType { ET_CALL, ET_RESUME_GENERATOR, ET_RESUME_VM, ET_RESUME_THROW_VM };
- SQVM(SQSharedState *ss);
- ~SQVM();
- bool Init(SQVM *friendvm, SQInteger stacksize);
- bool Execute(SQObjectPtr &func, SQInteger target, SQInteger nargs, SQInteger stackbase, SQObjectPtr &outres, SQBool raiseerror, ExecutionType et = ET_CALL);
- //starts a native call return when the NATIVE closure returns
- bool CallNative(SQNativeClosure *nclosure, SQInteger nargs, SQInteger stackbase, SQObjectPtr &retval,bool &suspend);
- //starts a SQUIRREL call in the same "Execution loop"
- bool StartCall(SQClosure *closure, SQInteger target, SQInteger nargs, SQInteger stackbase, bool tailcall);
- bool CreateClassInstance(SQClass *theclass, SQObjectPtr &inst, SQObjectPtr &constructor);
- //call a generic closure pure SQUIRREL or NATIVE
- bool Call(SQObjectPtr &closure, SQInteger nparams, SQInteger stackbase, SQObjectPtr &outres,SQBool raiseerror);
- SQRESULT Suspend();
-
- void CallDebugHook(SQInteger type,SQInteger forcedline=0);
- void CallErrorHandler(SQObjectPtr &e);
- bool Get(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &dest, bool raw, bool fetchroot);
- bool FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr &dest,bool raw);
- bool Set(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val, bool fetchroot);
- bool NewSlot(const SQObjectPtr &self, const SQObjectPtr &key, const SQObjectPtr &val,bool bstatic);
- bool DeleteSlot(const SQObjectPtr &self, const SQObjectPtr &key, SQObjectPtr &res);
- bool Clone(const SQObjectPtr &self, SQObjectPtr &target);
- bool ObjCmp(const SQObjectPtr &o1, const SQObjectPtr &o2,SQInteger &res);
- bool StringCat(const SQObjectPtr &str, const SQObjectPtr &obj, SQObjectPtr &dest);
- bool IsEqual(SQObjectPtr &o1,SQObjectPtr &o2,bool &res);
- void ToString(const SQObjectPtr &o,SQObjectPtr &res);
- SQString *PrintObjVal(const SQObject &o);
-
-
- void Raise_Error(const SQChar *s, ...);
- void Raise_Error(SQObjectPtr &desc);
- void Raise_IdxError(SQObject &o);
- void Raise_CompareError(const SQObject &o1, const SQObject &o2);
- void Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger type);
-
- void TypeOf(const SQObjectPtr &obj1, SQObjectPtr &dest);
- bool CallMetaMethod(SQDelegable *del, SQMetaMethod mm, SQInteger nparams, SQObjectPtr &outres);
- bool ArithMetaMethod(SQInteger op, const SQObjectPtr &o1, const SQObjectPtr &o2, SQObjectPtr &dest);
- bool Return(SQInteger _arg0, SQInteger _arg1, SQObjectPtr &retval);
- //new stuff
- _INLINE bool ARITH_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2);
- _INLINE bool BW_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,const SQObjectPtr &o2);
- _INLINE bool NEG_OP(SQObjectPtr &trg,const SQObjectPtr &o1);
- _INLINE bool CMP_OP(CmpOP op, const SQObjectPtr &o1,const SQObjectPtr &o2,SQObjectPtr &res);
- bool CLOSURE_OP(SQObjectPtr &target, SQFunctionProto *func);
- bool GETVARGV_OP(SQObjectPtr &target,SQObjectPtr &idx,CallInfo *ci);
- bool CLASS_OP(SQObjectPtr &target,SQInteger base,SQInteger attrs);
- bool GETPARENT_OP(SQObjectPtr &o,SQObjectPtr &target);
- //return true if the loop is finished
- bool FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr &o3,SQObjectPtr &o4,SQInteger arg_2,int exitpos,int &jump);
- bool DELEGATE_OP(SQObjectPtr &trg,SQObjectPtr &o1,SQObjectPtr &o2);
- _INLINE bool LOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr);
- _INLINE bool PLOCAL_INC(SQInteger op,SQObjectPtr &target, SQObjectPtr &a, SQObjectPtr &incr);
- _INLINE bool DerefInc(SQInteger op,SQObjectPtr &target, SQObjectPtr &self, SQObjectPtr &key, SQObjectPtr &incr, bool postfix);
- void PopVarArgs(VarArgs &vargs);
- void ClearStack(SQInteger last_top);
-#ifdef _DEBUG_DUMP
- void dumpstack(SQInteger stackbase=-1, bool dumpall = false);
-#endif
-
-#ifndef NO_GARBAGE_COLLECTOR
- void Mark(SQCollectable **chain);
-#endif
- void Finalize();
- void GrowCallStack() {
- SQInteger newsize = _alloccallsstacksize*2;
- _callstackdata.resize(newsize);
- _callsstack = &_callstackdata[0];
- _alloccallsstacksize = newsize;
- }
- void Release(){ sq_delete(this,SQVM); } //does nothing
-////////////////////////////////////////////////////////////////////////////
- //stack functions for the api
- void Remove(SQInteger n);
-
- bool IsFalse(SQObjectPtr &o);
-
- void Pop();
- void Pop(SQInteger n);
- void Push(const SQObjectPtr &o);
- SQObjectPtr &Top();
- SQObjectPtr &PopGet();
- SQObjectPtr &GetUp(SQInteger n);
- SQObjectPtr &GetAt(SQInteger n);
-
- SQObjectPtrVec _stack;
- SQObjectPtrVec _vargsstack;
- SQInteger _top;
- SQInteger _stackbase;
- SQObjectPtr _roottable;
- SQObjectPtr _lasterror;
- SQObjectPtr _errorhandler;
- SQObjectPtr _debughook;
-
- SQObjectPtr temp_reg;
-
-
- CallInfo* _callsstack;
- SQInteger _callsstacksize;
- SQInteger _alloccallsstacksize;
- sqvector<CallInfo> _callstackdata;
-
- ExceptionsTraps _etraps;
- CallInfo *ci;
- void *_foreignptr;
- //VMs sharing the same state
- SQSharedState *_sharedstate;
- SQInteger _nnativecalls;
- //suspend infos
- SQBool _suspended;
- SQBool _suspended_root;
- SQInteger _suspended_target;
- SQInteger _suspended_traps;
- VarArgs _suspend_varargs;
-};
-
-struct AutoDec{
- AutoDec(SQInteger *n) { _n = n; }
- ~AutoDec() { (*_n)--; }
- SQInteger *_n;
-};
-
-inline SQObjectPtr &stack_get(HSQUIRRELVM v,SQInteger idx){return ((idx>=0)?(v->GetAt(idx+v->_stackbase-1)):(v->GetUp(idx)));}
-
-#define _ss(_vm_) (_vm_)->_sharedstate
-
-#ifndef NO_GARBAGE_COLLECTOR
-#define _opt_ss(_vm_) (_vm_)->_sharedstate
-#else
-#define _opt_ss(_vm_) NULL
-#endif
-
-#define PUSH_CALLINFO(v,nci){ \
- if(v->_callsstacksize == v->_alloccallsstacksize) { \
- v->GrowCallStack(); \
- } \
- v->ci = &v->_callsstack[v->_callsstacksize]; \
- *(v->ci) = nci; \
- v->_callsstacksize++; \
-}
-
-#define POP_CALLINFO(v){ \
- v->_callsstacksize--; \
- v->ci->_closure.Null(); \
- if(v->_callsstacksize) \
- v->ci = &v->_callsstack[v->_callsstacksize-1] ; \
- else \
- v->ci = NULL; \
-}
-#endif //_SQVM_H_
+++ /dev/null
-// $Id$
-//
-// SuperTux (Statistics module)
-// Copyright (C) 2004 Ricardo Cruz <rick2@aeiou.pt>
-// Copyright (C) 2006 Ondrej Hosek <ondra.hosek@gmail.com>
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include <config.h>
-
-#include <assert.h>
-#include <math.h>
-#include <sstream>
-#include <iomanip>
-#include <limits>
-#include "video/drawing_context.hpp"
-#include "gettext.hpp"
-#include "lisp/writer.hpp"
-#include "lisp/lisp.hpp"
-#include "resources.hpp"
-#include "main.hpp"
-#include "statistics.hpp"
-#include "log.hpp"
-#include "scripting/squirrel_util.hpp"
-
-namespace {
- const int nv_coins = std::numeric_limits<int>::min();
- const int nv_badguys = std::numeric_limits<int>::min();
- const float nv_time = std::numeric_limits<float>::max();
- const int nv_secrets = std::numeric_limits<int>::min();
-}
-
-float WMAP_INFO_LEFT_X;
-float WMAP_INFO_RIGHT_X;
-float WMAP_INFO_TOP_Y1;
-float WMAP_INFO_TOP_Y2;
-
-Statistics::Statistics() : coins(nv_coins), total_coins(nv_coins), badguys(nv_badguys), total_badguys(nv_badguys), time(nv_time), secrets(nv_secrets), total_secrets(nv_secrets), valid(true)
-{
- WMAP_INFO_LEFT_X = (SCREEN_WIDTH/2 + 80) + 32;
- WMAP_INFO_RIGHT_X = SCREEN_WIDTH/2 + 368;
- WMAP_INFO_TOP_Y1 = SCREEN_HEIGHT/2 + 172 - 16;
- WMAP_INFO_TOP_Y2 = SCREEN_HEIGHT/2 + 172;
-}
-
-Statistics::~Statistics()
-{
-}
-
-/*
-void
-Statistics::parse(const lisp::Lisp& reader)
-{
- reader.get("coins-collected", coins);
- reader.get("coins-collected-total", total_coins);
- reader.get("badguys-killed", badguys);
- reader.get("badguys-killed-total", total_badguys);
- reader.get("time-needed", time);
- reader.get("secrets-found", secrets);
- reader.get("secrets-found-total", total_secrets);
-}
-
-void
-Statistics::write(lisp::Writer& writer)
-{
- writer.write("coins-collected", coins);
- writer.write("coins-collected-total", total_coins);
- writer.write("badguys-killed", badguys);
- writer.write("badguys-killed-total", total_badguys);
- writer.write("time-needed", time);
- writer.write("secrets-found", secrets);
- writer.write("secrets-found-total", total_secrets);
-}
-*/
-
-void
-Statistics::serialize_to_squirrel(HSQUIRRELVM vm)
-{
- // TODO: there's some bug in the unserialization routines that breaks stuff when an empty statistics table is written, so -- as a workaround -- let's make sure we will actually write something first
- if (!((coins != nv_coins) || (total_coins != nv_coins) || (badguys != nv_badguys) || (total_badguys != nv_badguys) || (time != nv_time) || (secrets != nv_secrets) || (total_secrets != nv_secrets))) return;
-
- sq_pushstring(vm, "statistics", -1);
- sq_newtable(vm);
- if (coins != nv_coins) Scripting::store_int(vm, "coins-collected", coins);
- if (total_coins != nv_coins) Scripting::store_int(vm, "coins-collected-total", total_coins);
- if (badguys != nv_badguys) Scripting::store_int(vm, "badguys-killed", badguys);
- if (total_badguys != nv_badguys) Scripting::store_int(vm, "badguys-killed-total", total_badguys);
- if (time != nv_time) Scripting::store_float(vm, "time-needed", time);
- if (secrets != nv_secrets) Scripting::store_int(vm, "secrets-found", secrets);
- if (total_secrets != nv_secrets) Scripting::store_int(vm, "secrets-found-total", total_secrets);
- sq_createslot(vm, -3);
-}
-
-void
-Statistics::unserialize_from_squirrel(HSQUIRRELVM vm)
-{
- sq_pushstring(vm, "statistics", -1);
- if(SQ_FAILED(sq_get(vm, -2))) {
- return;
- }
- Scripting::get_int(vm, "coins-collected", coins);
- Scripting::get_int(vm, "coins-collected-total", total_coins);
- Scripting::get_int(vm, "badguys-killed", badguys);
- Scripting::get_int(vm, "badguys-killed-total", total_badguys);
- Scripting::get_float(vm, "time-needed", time);
- Scripting::get_int(vm, "secrets-found", secrets);
- Scripting::get_int(vm, "secrets-found-total", total_secrets);
- sq_pop(vm, 1);
-}
-
-void
-Statistics::draw_worldmap_info(DrawingContext& context)
-{
- // skip draw if level was never played
- if (coins == nv_coins) return;
-
- // skip draw if stats were declared invalid
- if (!valid) return;
-
- context.draw_text(small_font, std::string("- ") + _("Best Level Statistics") + " -", Vector((WMAP_INFO_LEFT_X + WMAP_INFO_RIGHT_X) / 2, WMAP_INFO_TOP_Y1), ALIGN_CENTER, LAYER_GUI,Statistics::header_color);
-
- std::string caption_buf;
- std::string stat_buf;
- float posy = WMAP_INFO_TOP_Y2;
- for (int stat_no = 0; stat_no < 4; stat_no++) {
- switch (stat_no)
- {
- case 0:
- caption_buf = _("Max coins collected:");
- stat_buf = coins_to_string(coins, total_coins);
- break;
- case 1:
- caption_buf = _("Max fragging:");
- stat_buf = frags_to_string(badguys, total_badguys);
- break;
- case 2:
- caption_buf = _("Min time needed:");
- stat_buf = time_to_string(time);
- break;
- case 3:
- caption_buf = _("Max secrets found:");
- stat_buf = secrets_to_string(secrets, total_secrets);
- break;
- default:
- log_debug << "Invalid stat requested to be drawn" << std::endl;
- break;
- }
-
- context.draw_text(small_font, caption_buf, Vector(WMAP_INFO_LEFT_X, posy), ALIGN_LEFT, LAYER_GUI, Statistics::header_color);
- context.draw_text(small_font, stat_buf, Vector(WMAP_INFO_RIGHT_X, posy), ALIGN_RIGHT, LAYER_GUI, Statistics::header_color);
- posy += small_font->get_height() + 2;
- }
-
-}
-
-void
-Statistics::draw_endseq_panel(DrawingContext& context, Statistics* best_stats, Surface* backdrop)
-{
- // skip draw if level was never played
- // TODO: do we need this?
- if (coins == nv_coins) return;
-
- // skip draw if stats were declared invalid
- if (!valid) return;
-
- // abort if we have no backdrop
- if (!backdrop) return;
-
- int box_w = 220+110+110;
- int box_h = 30+20+20+20;
- int box_x = (int)((SCREEN_WIDTH - box_w) / 2);
- int box_y = (int)(SCREEN_HEIGHT / 2) - box_h;
-
- int bd_w = (int)backdrop->get_width();
- int bd_h = (int)backdrop->get_height();
- int bd_x = (int)((SCREEN_WIDTH - bd_w) / 2);
- int bd_y = box_y + (box_h / 2) - (bd_h / 2);
-
- int col1_x = box_x;
- int col2_x = col1_x+200;
- int col3_x = col2_x+130;
-
- int row1_y = box_y;
- int row2_y = row1_y+30;
- int row3_y = row2_y+20;
- int row4_y = row3_y+20;
-
- context.push_transform();
- context.set_alpha(0.5);
- context.draw_surface(backdrop, Vector(bd_x, bd_y), LAYER_GUI);
- context.pop_transform();
-
- context.draw_text(normal_font, _("You"), Vector(col2_x, row1_y), ALIGN_LEFT, LAYER_GUI, Statistics::header_color);
- context.draw_text(normal_font, _("Best"), Vector(col3_x, row1_y), ALIGN_LEFT, LAYER_GUI, Statistics::header_color);
-
- context.draw_text(normal_font, _("Coins"), Vector(col2_x-16, row3_y), ALIGN_RIGHT, LAYER_GUI, Statistics::header_color);
- int coins_best = (best_stats && (best_stats->coins > coins)) ? best_stats->coins : coins;
- int total_coins_best = (best_stats && (best_stats->total_coins > total_coins)) ? best_stats->total_coins : total_coins;
- context.draw_text(normal_font, coins_to_string(coins, total_coins), Vector(col2_x, row3_y), ALIGN_LEFT, LAYER_GUI, Statistics::text_color);
- context.draw_text(normal_font, coins_to_string(coins_best, total_coins_best), Vector(col3_x, row3_y), ALIGN_LEFT, LAYER_GUI, Statistics::text_color);
-
- context.draw_text(normal_font, _("Secrets"), Vector(col2_x-16, row4_y), ALIGN_RIGHT, LAYER_GUI, Statistics::header_color);
- int secrets_best = (best_stats && (best_stats->secrets > secrets)) ? best_stats->secrets : secrets;
- int total_secrets_best = (best_stats && (best_stats->total_secrets > total_secrets)) ? best_stats->total_secrets : total_secrets;
- context.draw_text(normal_font, secrets_to_string(secrets, total_secrets), Vector(col2_x, row4_y), ALIGN_LEFT, LAYER_GUI, Statistics::text_color);
- context.draw_text(normal_font, secrets_to_string(secrets_best, total_secrets_best), Vector(col3_x, row4_y), ALIGN_LEFT, LAYER_GUI, Statistics::text_color);
-
- context.draw_text(normal_font, _("Time"), Vector(col2_x-16, row2_y), ALIGN_RIGHT, LAYER_GUI, Statistics::header_color);
- float time_best = (best_stats && (best_stats->time < time)) ? best_stats->time : time;
- context.draw_text(normal_font, time_to_string(time), Vector(col2_x, row2_y), ALIGN_LEFT, LAYER_GUI, Statistics::text_color);
- context.draw_text(normal_font, time_to_string(time_best), Vector(col3_x, row2_y), ALIGN_LEFT, LAYER_GUI, Statistics::text_color);
-}
-
-void
-Statistics::zero()
-{
- reset();
- total_coins = 0;
- total_badguys = 0;
- total_secrets = 0;
-}
-
-void
-Statistics::reset()
-{
- coins = 0;
- badguys = 0;
- time = 0;
- secrets = 0;
-}
-
-void
-Statistics::merge(const Statistics& s2)
-{
- if (!s2.valid) return;
- coins = std::max(coins, s2.coins);
- total_coins = s2.total_coins;
- badguys = std::max(badguys, s2.badguys);
- total_badguys = s2.total_badguys;
- time = std::min(time, s2.time);
- secrets = std::max(secrets, s2.secrets);
- total_secrets = s2.total_secrets;
-}
-
-void
-Statistics::operator+=(const Statistics& s2)
-{
- if (!s2.valid) return;
- if (s2.coins != nv_coins) coins += s2.coins;
- if (s2.total_coins != nv_coins) total_coins += s2.total_coins;
- if (s2.badguys != nv_badguys) badguys += s2.badguys;
- if (s2.total_badguys != nv_badguys) total_badguys += s2.total_badguys;
- if (s2.time != nv_time) time += s2.time;
- if (s2.secrets != nv_secrets) secrets += s2.secrets;
- if (s2.total_secrets != nv_secrets) total_secrets += s2.total_secrets;
-}
-
-void
-Statistics::declare_invalid()
-{
- valid = false;
-}
-
-std::string
-Statistics::coins_to_string(int coins, int total_coins) {
- std::ostringstream os;
- os << std::min(coins, 999) << "/" << std::min(total_coins, 999);
- return os.str();
-}
-
-std::string
-Statistics::frags_to_string(int badguys, int total_badguys) {
- std::ostringstream os;
- os << std::min(badguys, 999) << "/" << std::min(total_badguys, 999);
- return os.str();
-}
-
-std::string
-Statistics::time_to_string(float time) {
- int time_csecs = std::min(static_cast<int>(time * 100), 99 * 6000 + 9999);
- int mins = (time_csecs / 6000);
- int secs = (time_csecs % 6000) / 100;
- int cscs = (time_csecs % 6000) % 100;
-
- std::ostringstream os;
- os << std::setw(2) << std::setfill('0') << mins << ":" << std::setw(2) << std::setfill('0') << secs << "." << std::setw(2) << std::setfill('0') << cscs;
- return os.str();
-}
-
-std::string
-Statistics::secrets_to_string(int secrets, int total_secrets) {
- std::ostringstream os;
- os << std::min(secrets, 999) << "/" << std::min(total_secrets, 999);
- return os.str();
-}
-
+++ /dev/null
-// $Id$
-//
-// SuperTux (Statistics module)
-// Copyright (C) 2004 Ricardo Cruz <rick2@aeiou.pt>
-// Copyright (C) 2006 Ondrej Hosek <ondra.hosek@gmail.com>
-// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#ifndef SUPERTUX_STATISTICS_H
-#define SUPERTUX_STATISTICS_H
-
-#include <squirrel.h>
-#include "video/color.hpp"
-
-namespace lisp { class Writer; }
-namespace lisp { class Lisp; }
-class Surface;
-class DrawingContext;
-
-/** This class is a layer between level and worldmap to keep
- * track of stuff like scores, and minor, but funny things, like
- * number of jumps and stuff */
-class Statistics
-{
- static Color header_color;
- static Color text_color;
-public:
- int coins; /**< coins collected */
- int total_coins; /**< coins in level */
- int badguys; /**< badguys actively killed */
- int total_badguys; /**< (vincible) badguys in level */
- float time; /**< seconds needed */
- int secrets; /**< secret areas found */
- int total_secrets; /**< secret areas in level */
-
-public:
- Statistics(); /**< Creates new statistics, call reset() before counting */
- ~Statistics();
-
- /// read statistics from lisp file
- //void parse(const lisp::Lisp& lisp);
- /// write statistics to lisp file
- //void write(lisp::Writer& writer);
-
- /**
- * serialize statistics object as squirrel table "statistics"
- */
- void serialize_to_squirrel(HSQUIRRELVM vm);
-
- /**
- * unserialize statistics object from squirrel table "statistics"
- */
- void unserialize_from_squirrel(HSQUIRRELVM vm);
-
- void draw_worldmap_info(DrawingContext& context); /**< draw worldmap stat HUD */
- void draw_endseq_panel(DrawingContext& context, Statistics* best_stats, Surface* backdrop); /**< draw panel shown during level's end sequence */
-
- void zero(); /**< Set stats to zero */
- void reset(); /**< Set stats (but not totals) to zero */
- void merge(const Statistics& stats); /**< Given another Statistics object finds the best of each one */
- void operator+=(const Statistics& o); /**< Add two Statistics objects */
-
- void declare_invalid(); /**< marks statistics as invalid for their entire lifetime (e.g. after cheating). Invalid statistics will not be merged or drawn. */
-
- static std::string coins_to_string(int coins, int total_coins);
- static std::string frags_to_string(int badguys, int total_badguys);
- static std::string time_to_string(float time);
- static std::string secrets_to_string(int secrets, int total_secrets);
-
-private:
- bool valid; /**< stores whether these statistics can be trusted */
-
-};
-
-#endif /*SUPERTUX_STATISTICS_H*/
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include "supertux/collision.hpp"
+
+#include <algorithm>
+
+#include "math/aatriangle.hpp"
+
+namespace collision {
+
+bool intersects(const Rect& r1, const Rect& r2)
+{
+ if(r1.p2.x < r2.p1.x || r1.p1.x > r2.p2.x)
+ return false;
+ if(r1.p2.y < r2.p1.y || r1.p1.y > r2.p2.y)
+ return false;
+
+ return true;
+}
+
+//---------------------------------------------------------------------------
+
+namespace {
+inline void makePlane(const Vector& p1, const Vector& p2, Vector& n, float& c)
+{
+ n = Vector(p2.y-p1.y, p1.x-p2.x);
+ c = -(p2 * n);
+ float nval = n.norm();
+ n /= nval;
+ c /= nval;
+}
+
+}
+
+bool rectangle_aatriangle(Constraints* constraints, const Rect& rect,
+ const AATriangle& triangle, const Vector& addl_ground_movement)
+{
+ if(!intersects(rect, (const Rect&) triangle))
+ return false;
+
+ Vector normal;
+ float c;
+ Vector p1;
+ Rect area;
+ switch(triangle.dir & AATriangle::DEFORM_MASK) {
+ case 0:
+ area.p1 = triangle.p1;
+ area.p2 = triangle.p2;
+ break;
+ case AATriangle::DEFORM1:
+ area.p1 = Vector(triangle.p1.x, triangle.p1.y + triangle.get_height()/2);
+ area.p2 = triangle.p2;
+ break;
+ case AATriangle::DEFORM2:
+ area.p1 = triangle.p1;
+ area.p2 = Vector(triangle.p2.x, triangle.p1.y + triangle.get_height()/2);
+ break;
+ case AATriangle::DEFORM3:
+ area.p1 = triangle.p1;
+ area.p2 = Vector(triangle.p1.x + triangle.get_width()/2, triangle.p2.y);
+ break;
+ case AATriangle::DEFORM4:
+ area.p1 = Vector(triangle.p1.x + triangle.get_width()/2, triangle.p1.y);
+ area.p2 = triangle.p2;
+ break;
+ default:
+ assert(false);
+ }
+
+ switch(triangle.dir & AATriangle::DIRECTION_MASK) {
+ case AATriangle::SOUTHWEST:
+ p1 = Vector(rect.p1.x, rect.p2.y);
+ makePlane(area.p1, area.p2, normal, c);
+ break;
+ case AATriangle::NORTHEAST:
+ p1 = Vector(rect.p2.x, rect.p1.y);
+ makePlane(area.p2, area.p1, normal, c);
+ break;
+ case AATriangle::SOUTHEAST:
+ p1 = rect.p2;
+ makePlane(Vector(area.p1.x, area.p2.y),
+ Vector(area.p2.x, area.p1.y), normal, c);
+ break;
+ case AATriangle::NORTHWEST:
+ p1 = rect.p1;
+ makePlane(Vector(area.p2.x, area.p1.y),
+ Vector(area.p1.x, area.p2.y), normal, c);
+ break;
+ default:
+ assert(false);
+ }
+
+ float n_p1 = -(normal * p1);
+ float depth = n_p1 - c;
+ if(depth < 0)
+ return false;
+
+#if 0
+ std::cout << "R: " << rect << " Tri: " << triangle << "\n";
+ std::cout << "Norm: " << normal << " Depth: " << depth << "\n";
+#endif
+
+ Vector outvec = normal * (depth + 0.2f);
+
+ const float RDELTA = 3;
+ if(p1.x < area.p1.x - RDELTA || p1.x > area.p2.x + RDELTA
+ || p1.y < area.p1.y - RDELTA || p1.y > area.p2.y + RDELTA) {
+ set_rectangle_rectangle_constraints(constraints, rect, area);
+ constraints->hit.left = false;
+ constraints->hit.right = false;
+ } else {
+ if(outvec.x < 0) {
+ constraints->right = rect.get_right() + outvec.x;
+ } else {
+ constraints->left = rect.get_left() + outvec.x;
+ }
+
+ if(outvec.y < 0) {
+ constraints->bottom = rect.get_bottom() + outvec.y;
+ constraints->hit.bottom = true;
+ constraints->ground_movement += addl_ground_movement;
+ } else {
+ constraints->top = rect.get_top() + outvec.y;
+ constraints->hit.top = true;
+ }
+ constraints->hit.slope_normal = normal;
+ }
+
+ return true;
+}
+
+void set_rectangle_rectangle_constraints(Constraints* constraints,
+ const Rect& r1, const Rect& r2, const Vector& addl_ground_movement)
+{
+ float itop = r1.get_bottom() - r2.get_top();
+ float ibottom = r2.get_bottom() - r1.get_top();
+ float ileft = r1.get_right() - r2.get_left();
+ float iright = r2.get_right() - r1.get_left();
+
+ float vert_penetration = std::min(itop, ibottom);
+ float horiz_penetration = std::min(ileft, iright);
+ if(vert_penetration < horiz_penetration) {
+ if(itop < ibottom) {
+ constraints->bottom = std::min(constraints->bottom, r2.get_top());
+ constraints->hit.bottom = true;
+ constraints->ground_movement += addl_ground_movement;
+ } else {
+ constraints->top = std::max(constraints->top, r2.get_bottom());
+ constraints->hit.top = true;
+ }
+ } else {
+ if(ileft < iright) {
+ constraints->right = std::min(constraints->right, r2.get_left());
+ constraints->hit.right = true;
+ } else {
+ constraints->left = std::max(constraints->left, r2.get_right());
+ constraints->hit.left = true;
+ }
+ }
+}
+
+}
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_SUPERTUX_COLLISION_HPP
+#define HEADER_SUPERTUX_SUPERTUX_COLLISION_HPP
+
+#include "supertux/collision_hit.hpp"
+#include <limits>
+
+class Vector;
+class Rect;
+class AATriangle;
+
+namespace collision {
+
+class Constraints
+{
+public:
+ Constraints() {
+ float infinity = (std::numeric_limits<float>::has_infinity ?
+ std::numeric_limits<float>::infinity() :
+ std::numeric_limits<float>::max());
+ left = -infinity;
+ right = infinity;
+ top = -infinity;
+ bottom = infinity;
+ }
+
+ bool has_constraints() const {
+ float infinity = (std::numeric_limits<float>::has_infinity ?
+ std::numeric_limits<float>::infinity() :
+ std::numeric_limits<float>::max());
+ return left > -infinity || right < infinity
+ || top > -infinity || bottom < infinity;
+ }
+
+ float left;
+ float right;
+ float top;
+ float bottom;
+ Vector ground_movement;
+ CollisionHit hit;
+};
+
+/** checks if 2 rectangle intersect each other */
+bool intersects(const Rect& r1, const Rect& r2);
+
+/** does collision detection between a rectangle and an axis aligned triangle
+ * Returns true in case of a collision and fills in the hit structure then.
+ */
+bool rectangle_aatriangle(Constraints* constraints, const Rect& rect,
+ const AATriangle& triangle, const Vector& addl_ground_movement = Vector(0,0));
+
+void set_rectangle_rectangle_constraints(Constraints* constraints,
+ const Rect& r1, const Rect& r2, const Vector& addl_ground_movement = Vector(0,0));
+
+} // namespace collision
+
+#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_SUPERTUX_COLLISION_HIT_HPP
+#define HEADER_SUPERTUX_SUPERTUX_COLLISION_HIT_HPP
+
+#include "math/vector.hpp"
+
+/**
+ * Used as return value for the collision functions, to indicate how the
+ * collision should be handled
+ */
+enum HitResponse
+{
+ /// don't move the object
+ ABORT_MOVE = 0,
+ /// move object out of collision and check for collisions again
+ /// if this happens to often then the move will just be aborted
+ CONTINUE,
+ /// do the move ignoring the collision
+ FORCE_MOVE,
+ /// passes movement to collided object
+ PASS_MOVEMENT,
+
+ /// the object should not appear solid
+ PASSTHROUGH,
+ /// the object should appear solid
+ SOLID
+};
+
+/**
+ * This class collects data about a collision
+ */
+class CollisionHit
+{
+public:
+ CollisionHit() :
+ left(false),
+ right(false),
+ top(false),
+ bottom(false),
+ crush(false),
+ slope_normal()
+ {}
+
+ bool left, right;
+ bool top, bottom;
+ bool crush;
+
+ Vector slope_normal;
+
+private:
+ CollisionHit(const CollisionHit&);
+};
+
+#endif
+
+/* EOF */
--- /dev/null
+#include "video/color.hpp"
+
+namespace LevelIntro {
+Color header_color(1.0,1.0,0.6);
+Color author_color(1.0,1.0,1.0);
+Color stat_hdr_color(0.2,0.5,1.0);
+Color stat_color(1.0,1.0,1.0);
+}
+
+namespace Statistics {
+Color header_color(1.0,1.0,1.0);
+Color text_color(1.0,1.0,0.6);
+}
+
+namespace Menu {
+Color default_color(1.0,1.0,1.0);
+Color active_color(0.2,0.5,1.0);
+Color inactive_color(0.5,0.5,0.5);
+Color label_color(0.0,1.0,1.0);
+Color field_color(1.0,1.0,0.6);
+}
+
+namespace PlayerStatus {
+Color text_color(1.0,1.0,0.6);
+}
+
+namespace TextObject {
+Color default_color(1.0,1.0,1.0);
+}
+
+namespace FloatingText {
+Color text_color(1.0,1.0,0.6);
+}
+
+namespace LevelTime {
+Color text_color(1.0,1.0,0.6);
+}
+
+namespace SecretAreaTrigger {
+Color text_color(1.0,1.0,0.6);
+}
+
+namespace Climbable {
+Color text_color(1.0,1.0,0.6);
+}
+
+namespace WorldMapNS {
+namespace WorldMap {
+Color level_title_color(1.0,1.0,1.0);
+Color message_color(1.0,1.0,0.6);
+Color teleporter_message_color(1.0,1.0,1.0);
+}}
+
+namespace TextScroller {
+Color small_color(1.0,1.0,1.0);
+Color heading_color(1.0,1.0,0.6);
+Color reference_color(0.2,0.6,1.0);
+Color normal_color(1.0,1.0,1.0);
+}
+
+/* EOF */
--- /dev/null
+// SuperTux - Console
+// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include "supertux/console.hpp"
+
+#include <math.h>
+
+#include "physfs/physfs_stream.hpp"
+#include "scripting/squirrel_util.hpp"
+#include "supertux/gameconfig.hpp"
+#include "supertux/main.hpp"
+#include "video/drawing_context.hpp"
+
+/// speed (pixels/s) the console closes
+static const float FADE_SPEED = 1;
+
+Console::Console() :
+ history_position(history.end()),
+ vm(NULL),
+ backgroundOffset(0),
+ height(0),
+ alpha(1.0),
+ offset(0),
+ focused(false),
+ stayOpen(0)
+{
+ fontheight = 8;
+}
+
+Console::~Console()
+{
+ if(vm != NULL) {
+ sq_release(Scripting::global_vm, &vm_object);
+ }
+}
+
+void
+Console::init_graphics()
+{
+ font.reset(new Font(Font::FIXED,"fonts/andale12.stf",1));
+ fontheight = font->get_height();
+ background.reset(new Surface("images/engine/console.png"));
+ background2.reset(new Surface("images/engine/console2.png"));
+}
+
+void
+Console::flush(ConsoleStreamBuffer* buffer)
+{
+ if (buffer == &outputBuffer) {
+ std::string s = outputBuffer.str();
+ if ((s.length() > 0) && ((s[s.length()-1] == '\n') || (s[s.length()-1] == '\r'))) {
+ while ((s[s.length()-1] == '\n') || (s[s.length()-1] == '\r')) s.erase(s.length()-1);
+ addLines(s);
+ outputBuffer.str(std::string());
+ }
+ }
+}
+
+void
+Console::ready_vm()
+{
+ if(vm == NULL) {
+ vm = Scripting::global_vm;
+ HSQUIRRELVM new_vm = sq_newthread(vm, 16);
+ if(new_vm == NULL)
+ throw Scripting::SquirrelError(vm, "Couldn't create new VM thread for console");
+
+ // store reference to thread
+ sq_resetobject(&vm_object);
+ if(SQ_FAILED(sq_getstackobj(vm, -1, &vm_object)))
+ throw Scripting::SquirrelError(vm, "Couldn't get vm object for console");
+ sq_addref(vm, &vm_object);
+ sq_pop(vm, 1);
+
+ // create new roottable for thread
+ sq_newtable(new_vm);
+ sq_pushroottable(new_vm);
+ if(SQ_FAILED(sq_setdelegate(new_vm, -2)))
+ throw Scripting::SquirrelError(new_vm, "Couldn't set console_table delegate");
+
+ sq_setroottable(new_vm);
+
+ vm = new_vm;
+
+ try {
+ std::string filename = "scripts/console.nut";
+ IFileStream stream(filename);
+ Scripting::compile_and_run(vm, stream, filename);
+ } catch(std::exception& e) {
+ log_warning << "Couldn't load console.nut: " << e.what() << std::endl;
+ }
+ }
+}
+
+void
+Console::execute_script(const std::string& command)
+{
+ using namespace Scripting;
+
+ ready_vm();
+
+ SQInteger oldtop = sq_gettop(vm);
+ try {
+ if(SQ_FAILED(sq_compilebuffer(vm, command.c_str(), command.length(),
+ "", SQTrue)))
+ throw SquirrelError(vm, "Couldn't compile command");
+
+ sq_pushroottable(vm);
+ if(SQ_FAILED(sq_call(vm, 1, SQTrue, SQTrue)))
+ throw SquirrelError(vm, "Problem while executing command");
+
+ if(sq_gettype(vm, -1) != OT_NULL)
+ addLines(squirrel2string(vm, -1));
+ } catch(std::exception& e) {
+ addLines(e.what());
+ }
+ SQInteger newtop = sq_gettop(vm);
+ if(newtop < oldtop) {
+ log_fatal << "Script destroyed squirrel stack..." << std::endl;
+ } else {
+ sq_settop(vm, oldtop);
+ }
+}
+
+void
+Console::input(char c)
+{
+ inputBuffer.insert(inputBufferPosition, 1, c);
+ inputBufferPosition++;
+}
+
+void
+Console::backspace()
+{
+ if ((inputBufferPosition > 0) && (inputBuffer.length() > 0)) {
+ inputBuffer.erase(inputBufferPosition-1, 1);
+ inputBufferPosition--;
+ }
+}
+
+void
+Console::eraseChar()
+{
+ if (inputBufferPosition < (int)inputBuffer.length()) {
+ inputBuffer.erase(inputBufferPosition, 1);
+ }
+}
+
+void
+Console::enter()
+{
+ addLines("> "+inputBuffer);
+ parse(inputBuffer);
+ inputBuffer = "";
+ inputBufferPosition = 0;
+}
+
+void
+Console::scroll(int numLines)
+{
+ offset += numLines;
+ if (offset > 0) offset = 0;
+}
+
+void
+Console::show_history(int offset)
+{
+ while ((offset > 0) && (history_position != history.end())) {
+ history_position++;
+ offset--;
+ }
+ while ((offset < 0) && (history_position != history.begin())) {
+ history_position--;
+ offset++;
+ }
+ if (history_position == history.end()) {
+ inputBuffer = "";
+ inputBufferPosition = 0;
+ } else {
+ inputBuffer = *history_position;
+ inputBufferPosition = inputBuffer.length();
+ }
+}
+
+void
+Console::move_cursor(int offset)
+{
+ if (offset == -65535) inputBufferPosition = 0;
+ if (offset == +65535) inputBufferPosition = inputBuffer.length();
+ inputBufferPosition+=offset;
+ if (inputBufferPosition < 0) inputBufferPosition = 0;
+ if (inputBufferPosition > (int)inputBuffer.length()) inputBufferPosition = inputBuffer.length();
+}
+
+// Helper functions for Console::autocomplete
+// TODO: Fix rough documentation
+namespace {
+
+void sq_insert_commands(std::list<std::string>& cmds, HSQUIRRELVM vm, std::string table_prefix, std::string search_prefix);
+
+/**
+ * Acts upon key,value on top of stack:
+ * Appends key (plus type-dependent suffix) to cmds if table_prefix+key starts with search_prefix;
+ * Calls sq_insert_commands if search_prefix starts with table_prefix+key (and value is a table/class/instance);
+ */
+void
+sq_insert_command(std::list<std::string>& cmds, HSQUIRRELVM vm, std::string table_prefix, std::string search_prefix)
+{
+ const SQChar* key_chars;
+ if (SQ_FAILED(sq_getstring(vm, -2, &key_chars))) return;
+ std::string key_string = table_prefix + key_chars;
+
+ switch (sq_gettype(vm, -1)) {
+ case OT_INSTANCE:
+ key_string+=".";
+ if (search_prefix.substr(0, key_string.length()) == key_string) {
+ sq_getclass(vm, -1);
+ sq_insert_commands(cmds, vm, key_string, search_prefix);
+ sq_pop(vm, 1);
+ }
+ break;
+ case OT_TABLE:
+ case OT_CLASS:
+ key_string+=".";
+ if (search_prefix.substr(0, key_string.length()) == key_string) {
+ sq_insert_commands(cmds, vm, key_string, search_prefix);
+ }
+ break;
+ case OT_CLOSURE:
+ case OT_NATIVECLOSURE:
+ key_string+="()";
+ break;
+ default:
+ break;
+ }
+
+ if (key_string.substr(0, search_prefix.length()) == search_prefix) {
+ cmds.push_back(key_string);
+ }
+
+}
+
+/**
+ * calls sq_insert_command for all entries of table/class on top of stack
+ */
+void
+sq_insert_commands(std::list<std::string>& cmds, HSQUIRRELVM vm, std::string table_prefix, std::string search_prefix)
+{
+ sq_pushnull(vm); // push iterator
+ while (SQ_SUCCEEDED(sq_next(vm,-2))) {
+ sq_insert_command(cmds, vm, table_prefix, search_prefix);
+ sq_pop(vm, 2); // pop key, val
+ }
+ sq_pop(vm, 1); // pop iterator
+}
+
+}
+// End of Console::autocomplete helper functions
+
+void
+Console::autocomplete()
+{
+ //int autocompleteFrom = inputBuffer.find_last_of(" ();+", inputBufferPosition);
+ int autocompleteFrom = inputBuffer.find_last_not_of("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_->.", inputBufferPosition);
+ if (autocompleteFrom != (int)std::string::npos) {
+ autocompleteFrom += 1;
+ } else {
+ autocompleteFrom = 0;
+ }
+ std::string prefix = inputBuffer.substr(autocompleteFrom, inputBufferPosition - autocompleteFrom);
+ addLines("> "+prefix);
+
+ std::list<std::string> cmds;
+
+ ready_vm();
+
+ // append all keys of the current root table to list
+ sq_pushroottable(vm); // push root table
+ while(true) {
+ // check all keys (and their children) for matches
+ sq_insert_commands(cmds, vm, "", prefix);
+
+ // cycle through parent(delegate) table
+ SQInteger oldtop = sq_gettop(vm);
+ if(SQ_FAILED(sq_getdelegate(vm, -1)) || oldtop == sq_gettop(vm)) {
+ break;
+ }
+ sq_remove(vm, -2); // remove old table
+ }
+ sq_pop(vm, 1); // remove table
+
+ // depending on number of hits, show matches or autocomplete
+ if (cmds.size() == 0) addLines("No known command starts with \""+prefix+"\"");
+ if (cmds.size() == 1) {
+ // one match: just replace input buffer with full command
+ std::string replaceWith = cmds.front();
+ inputBuffer.replace(autocompleteFrom, prefix.length(), replaceWith);
+ inputBufferPosition += (replaceWith.length() - prefix.length());
+ }
+ if (cmds.size() > 1) {
+ // multiple matches: show all matches and set input buffer to longest common prefix
+ std::string commonPrefix = cmds.front();
+ while (cmds.begin() != cmds.end()) {
+ std::string cmd = cmds.front();
+ cmds.pop_front();
+ addLines(cmd);
+ for (int n = commonPrefix.length(); n >= 1; n--) {
+ if (cmd.compare(0, n, commonPrefix) != 0) commonPrefix.resize(n-1); else break;
+ }
+ }
+ std::string replaceWith = commonPrefix;
+ inputBuffer.replace(autocompleteFrom, prefix.length(), replaceWith);
+ inputBufferPosition += (replaceWith.length() - prefix.length());
+ }
+}
+
+void
+Console::addLines(std::string s)
+{
+ std::istringstream iss(s);
+ std::string line;
+ while (std::getline(iss, line, '\n')) addLine(line);
+}
+
+void
+Console::addLine(std::string s)
+{
+ // output line to stderr
+ std::cerr << s << std::endl;
+
+ // wrap long lines
+ std::string overflow;
+ unsigned int line_count = 0;
+ do {
+ lines.push_front(Font::wrap_to_chars(s, 99, &overflow));
+ line_count++;
+ s = overflow;
+ } while (s.length() > 0);
+
+ // trim scrollback buffer
+ while (lines.size() >= 1000)
+ lines.pop_back();
+
+ // increase console height if necessary
+ if (height < 64) {
+ if(height < 4)
+ height = 4;
+ height += fontheight * line_count;
+ }
+
+ // reset console to full opacity
+ alpha = 1.0;
+
+ // increase time that console stays open
+ if(stayOpen < 6)
+ stayOpen += 1.5;
+}
+
+void
+Console::parse(std::string s)
+{
+ // make sure we actually have something to parse
+ if (s.length() == 0) return;
+
+ // add line to history
+ history.push_back(s);
+ history_position = history.end();
+
+ // split line into list of args
+ std::vector<std::string> args;
+ size_t start = 0;
+ size_t end = 0;
+ while (1) {
+ start = s.find_first_not_of(" ,", end);
+ end = s.find_first_of(" ,", start);
+ if (start == s.npos) break;
+ args.push_back(s.substr(start, end-start));
+ }
+
+ // command is args[0]
+ if (args.size() == 0) return;
+ std::string command = args.front();
+ args.erase(args.begin());
+
+ // ignore if it's an internal command
+ if (consoleCommand(command,args)) return;
+
+ try {
+ execute_script(s);
+ } catch(std::exception& e) {
+ addLines(e.what());
+ }
+
+}
+
+bool
+Console::consoleCommand(std::string /*command*/, std::vector<std::string> /*arguments*/)
+{
+ return false;
+}
+
+bool
+Console::hasFocus()
+{
+ return focused;
+}
+
+void
+Console::show()
+{
+ if(!g_config->console_enabled)
+ return;
+
+ focused = true;
+ height = 256;
+ alpha = 1.0;
+ SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
+}
+
+void
+Console::hide()
+{
+ focused = false;
+ height = 0;
+ stayOpen = 0;
+
+ // clear input buffer
+ inputBuffer = "";
+ inputBufferPosition = 0;
+ SDL_EnableKeyRepeat(0, SDL_DEFAULT_REPEAT_INTERVAL);
+}
+
+void
+Console::toggle()
+{
+ if (Console::hasFocus()) {
+ Console::hide();
+ }
+ else {
+ Console::show();
+ }
+}
+
+void
+Console::update(float elapsed_time)
+{
+ if(stayOpen > 0) {
+ stayOpen -= elapsed_time;
+ if(stayOpen < 0)
+ stayOpen = 0;
+ } else if(!focused && height > 0) {
+ alpha -= elapsed_time * FADE_SPEED;
+ if(alpha < 0) {
+ alpha = 0;
+ height = 0;
+ }
+ }
+}
+
+void
+Console::draw(DrawingContext& context)
+{
+ if (height == 0)
+ return;
+
+ int layer = LAYER_GUI + 1;
+
+ context.push_transform();
+ context.set_alpha(alpha);
+ context.draw_surface(background2.get(), Vector(SCREEN_WIDTH/2 - background->get_width()/2 - background->get_width() + backgroundOffset, height - background->get_height()), layer);
+ context.draw_surface(background2.get(), Vector(SCREEN_WIDTH/2 - background->get_width()/2 + backgroundOffset, height - background->get_height()), layer);
+ for (int x = (SCREEN_WIDTH/2 - background->get_width()/2 - (static_cast<int>(ceilf((float)SCREEN_WIDTH / (float)background->get_width()) - 1) * background->get_width())); x < SCREEN_WIDTH; x+=background->get_width()) {
+ context.draw_surface(background.get(), Vector(x, height - background->get_height()), layer);
+ }
+ backgroundOffset+=10;
+ if (backgroundOffset > (int)background->get_width()) backgroundOffset -= (int)background->get_width();
+
+ int lineNo = 0;
+
+ if (focused) {
+ lineNo++;
+ float py = height-4-1 * font->get_height();
+ context.draw_text(font.get(), "> "+inputBuffer, Vector(4, py), ALIGN_LEFT, layer);
+ if (SDL_GetTicks() % 1000 < 750) {
+ int cursor_px = 2 + inputBufferPosition;
+ context.draw_text(font.get(), "_", Vector(4 + (cursor_px * font->get_text_width("X")), py), ALIGN_LEFT, layer);
+ }
+ }
+
+ int skipLines = -offset;
+ for (std::list<std::string>::iterator i = lines.begin(); i != lines.end(); i++) {
+ if (skipLines-- > 0) continue;
+ lineNo++;
+ float py = height - 4 - lineNo*font->get_height();
+ if (py < -font->get_height()) break;
+ context.draw_text(font.get(), *i, Vector(4, py), ALIGN_LEFT, layer);
+ }
+ context.pop_transform();
+}
+
+Console* Console::instance = NULL;
+int Console::inputBufferPosition = 0;
+std::string Console::inputBuffer;
+ConsoleStreamBuffer Console::outputBuffer;
+std::ostream Console::output(&Console::outputBuffer);
+
+/* EOF */
--- /dev/null
+// SuperTux - Console
+// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_SUPERTUX_CONSOLE_HPP
+#define HEADER_SUPERTUX_SUPERTUX_CONSOLE_HPP
+
+#include <list>
+#include <memory>
+#include <squirrel.h>
+#include <sstream>
+#include <vector>
+
+class Console;
+class ConsoleStreamBuffer;
+class ConsoleCommandReceiver;
+class DrawingContext;
+class Surface;
+class Font;
+
+class Console
+{
+public:
+ Console();
+ ~Console();
+
+ static Console* instance;
+
+ static std::ostream output; /**< stream of characters to output to the console. Do not forget to send std::endl or to flush the stream. */
+
+ void init_graphics();
+
+ void input(char c); /**< add character to inputBuffer */
+ void backspace(); /**< delete character left of inputBufferPosition */
+ void eraseChar(); /**< delete character at inputBufferPosition */
+ void enter(); /**< process and clear input stream */
+ void scroll(int offset); /**< scroll console text up or down by @c offset lines */
+ void autocomplete(); /**< autocomplete current command */
+ void show_history(int offset); /**< move @c offset lines forward through history; Negative offset moves backward */
+ void move_cursor(int offset); /**< move the cursor @c offset chars to the right; Negative offset moves backward; 0xFFFF moves to the end */
+
+ void draw(DrawingContext& context); /**< draw the console in a DrawingContext */
+ void update(float elapsed_time);
+
+ void show(); /**< display the console */
+ void hide(); /**< hide the console */
+ void toggle(); /**< display the console if hidden, hide otherwise */
+
+ bool hasFocus(); /**< true if characters should be sent to the console instead of their normal target */
+
+ template<typename T> static bool string_is(std::string s) {
+ std::istringstream iss(s);
+ T i;
+ if ((iss >> i) && iss.eof()) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ template<typename T> static T string_to(std::string s) {
+ std::istringstream iss(s);
+ T i;
+ if ((iss >> i) && iss.eof()) {
+ return i;
+ } else {
+ return T();
+ }
+ }
+
+private:
+ std::list<std::string> history; /**< command history. New lines get added to back. */
+ std::list<std::string>::iterator history_position; /**< item of command history that is currently displayed */
+ std::list<std::string> lines; /**< backbuffer of lines sent to the console. New lines get added to front. */
+
+ std::auto_ptr<Surface> background; /**< console background image */
+ std::auto_ptr<Surface> background2; /**< second, moving console background image */
+
+ HSQUIRRELVM vm; /**< squirrel thread for the console (with custom roottable) */
+ HSQOBJECT vm_object;
+
+ int backgroundOffset; /**< current offset of scrolling background image */
+ float height; /**< height of the console in px */
+ float alpha;
+ int offset; /**< decrease to scroll text up */
+ bool focused; /**< true if console has input focus */
+ std::auto_ptr<Font> font;
+ float fontheight; /**< height of the font (this is a separate var, because the font could not be initialized yet but is needed in the addLine message */
+
+ float stayOpen;
+
+ static int inputBufferPosition; /**< position in inputBuffer before which to append new characters */
+ static std::string inputBuffer; /**< string used for keyboard input */
+ static ConsoleStreamBuffer outputBuffer; /**< stream buffer used by output stream */
+
+ void addLines(std::string s); /**< display a string of (potentially) multiple lines in the console */
+ void addLine(std::string s); /**< display a line in the console */
+ void parse(std::string s); /**< react to a given command */
+
+ /** ready a virtual machine instance, creating a new thread and loading default .nut files if needed */
+ void ready_vm();
+
+ /** execute squirrel script and output result */
+ void execute_script(const std::string& s);
+
+ bool consoleCommand(std::string command, std::vector<std::string> arguments); /**< process internal command; return false if command was unknown, true otherwise */
+
+ friend class ConsoleStreamBuffer;
+ void flush(ConsoleStreamBuffer* buffer); /**< act upon changes in a ConsoleStreamBuffer */
+
+private:
+ Console(const Console&);
+ Console & operator=(const Console&);
+};
+
+class ConsoleStreamBuffer : public std::stringbuf
+{
+public:
+ int sync()
+ {
+ int result = std::stringbuf::sync();
+ if(Console::instance != NULL)
+ Console::instance->flush(this);
+ return result;
+ }
+};
+
+#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2009 Mathnerd314
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_SUPERTUX_CONSTANTS_HPP
+#define HEADER_SUPERTUX_SUPERTUX_CONSTANTS_HPP
+
+//Useful constants
+
+// a small value... be careful as CD is very sensitive to it
+static const float DELTA = .0005f;
+
+// the engine will be run with a logical framerate of 64fps.
+// We chose 64fps here because it is a power of 2, so 1/64 gives an "even"
+// binary fraction...
+static const float LOGICAL_FPS = 64.0;
+
+// SHIFT_DELTA is used for sliding over 1-tile gaps and collision detection
+static const float SHIFT_DELTA = 7.0f;
+
+#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2008 Ryan Flegel <rflegel@gmail.com>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include "supertux/direction.hpp"
+
+std::ostream& operator<<(std::ostream& o, const Direction& dir)
+{
+ switch (dir)
+ {
+ case AUTO:
+ o << "auto";
+ break;
+ case LEFT:
+ o << "left";
+ break;
+ case RIGHT:
+ o << "right";
+ break;
+ case UP:
+ o << "up";
+ break;
+ case DOWN:
+ o << "down";
+ break;
+ }
+
+ return o;
+}
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_SUPERTUX_DIRECTION_HPP
+#define HEADER_SUPERTUX_SUPERTUX_DIRECTION_HPP
+
+#include <iostream>
+
+enum Direction { AUTO, LEFT, RIGHT, UP, DOWN };
+
+std::ostream& operator<<(std::ostream& o, const Direction& dir);
+
+#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include "supertux/fadeout.hpp"
+#include "supertux/main.hpp"
+#include "video/drawing_context.hpp"
+
+FadeOut::FadeOut(float fade_time, Color color)
+ : color(color), fade_time(fade_time), accum_time(0)
+{
+}
+
+FadeOut::~FadeOut()
+{
+}
+
+void
+FadeOut::update(float elapsed_time)
+{
+ accum_time += elapsed_time;
+ if(accum_time > fade_time)
+ accum_time = fade_time;
+}
+
+void
+FadeOut::draw(DrawingContext& context)
+{
+ Color col = color;
+ col.alpha = accum_time / fade_time;
+ context.draw_filled_rect(Vector(0, 0),
+ Vector(SCREEN_WIDTH, SCREEN_HEIGHT),
+ col, LAYER_GUI+1);
+}
+
+bool
+FadeOut::done()
+{
+ return accum_time >= fade_time;
+}
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_SUPERTUX_FADEOUT_HPP
+#define HEADER_SUPERTUX_SUPERTUX_FADEOUT_HPP
+
+#include "supertux/screen_fade.hpp"
+#include "video/color.hpp"
+
+/**
+ * Fades a screen towards a specific color
+ */
+class FadeOut : public ScreenFade
+{
+public:
+ FadeOut(float fade_time, Color dest_color = Color(0, 0, 0));
+ virtual ~FadeOut();
+
+ virtual void update(float elapsed_time);
+ virtual void draw(DrawingContext& context);
+
+ /// returns true if the effect is completed
+ virtual bool done();
+
+private:
+ Color color;
+ float fade_time;
+ float accum_time;
+};
+
+#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include "badguy/badguy.hpp"
+#include "object/block.hpp"
+#include "object/camera.hpp"
+#include "object/platform.hpp"
+#include "object/player.hpp"
+#include "object/tilemap.hpp"
+#include "supertux/flip_level_transformer.hpp"
+#include "supertux/sector.hpp"
+#include "supertux/spawn_point.hpp"
+
+void
+FlipLevelTransformer::transform_sector(Sector* sector)
+{
+ float height = sector->get_height();
+
+ for(Sector::GameObjects::iterator i = sector->gameobjects.begin();
+ i != sector->gameobjects.end(); ++i) {
+ GameObject* object = *i;
+
+ TileMap* tilemap = dynamic_cast<TileMap*> (object);
+ if(tilemap) {
+ transform_tilemap(tilemap);
+ }
+ Player* player = dynamic_cast<Player*> (object);
+ if(player) {
+ Vector pos = player->get_pos();
+ pos.y = height - pos.y - player->get_bbox().get_height();
+ player->move(pos);
+ continue;
+ }
+ BadGuy* badguy = dynamic_cast<BadGuy*> (object);
+ if(badguy) {
+ transform_badguy(height, badguy);
+ }
+ Platform* platform = dynamic_cast<Platform*> (object);
+ if(platform) {
+ transform_platform(height, *platform);
+ }
+ Block* block = dynamic_cast<Block*> (object);
+ if(block) {
+ transform_block(height, *block);
+ }
+ MovingObject* mobject = dynamic_cast<MovingObject*> (object);
+ if(mobject) {
+ transform_moving_object(height, mobject);
+ }
+ }
+ for(Sector::SpawnPoints::iterator i = sector->spawnpoints.begin();
+ i != sector->spawnpoints.end(); ++i) {
+ transform_spawnpoint(height, *i);
+ }
+
+ if(sector->camera != 0 && sector->player != 0)
+ sector->camera->reset(sector->player->get_pos());
+}
+
+void
+FlipLevelTransformer::transform_tilemap(TileMap* tilemap)
+{
+ for(size_t x = 0; x < tilemap->get_width(); ++x) {
+ for(size_t y = 0; y < tilemap->get_height()/2; ++y) {
+ // swap tiles
+ int y2 = tilemap->get_height()-1-y;
+ uint32_t t1 = tilemap->get_tile_id(x, y);
+ uint32_t t2 = tilemap->get_tile_id(x, y2);
+ tilemap->change(x, y, t2);
+ tilemap->change(x, y2, t1);
+ }
+ }
+ if(tilemap->get_drawing_effect() != 0) {
+ tilemap->set_drawing_effect(NO_EFFECT);
+ } else {
+ tilemap->set_drawing_effect(VERTICAL_FLIP);
+ }
+}
+
+void
+FlipLevelTransformer::transform_badguy(float height, BadGuy* badguy)
+{
+ Vector pos = badguy->get_start_position();
+ pos.y = height - pos.y;
+ badguy->set_start_position(pos);
+}
+
+void
+FlipLevelTransformer::transform_spawnpoint(float height, SpawnPoint* spawn)
+{
+ Vector pos = spawn->pos;
+ pos.y = height - pos.y;
+ spawn->pos = pos;
+}
+
+void
+FlipLevelTransformer::transform_moving_object(float height, MovingObject*object)
+{
+ Vector pos = object->get_pos();
+ pos.y = height - pos.y - object->get_bbox().get_height();
+ object->set_pos(pos);
+}
+
+void
+FlipLevelTransformer::transform_platform(float height, Platform& platform)
+{
+ Path& path = platform.get_path();
+ for (std::vector<Path::Node>::iterator i = path.nodes.begin(); i != path.nodes.end(); i++) {
+ Vector& pos = i->position;
+ pos.y = height - pos.y - platform.get_bbox().get_height();
+ }
+}
+
+void
+FlipLevelTransformer::transform_block(float height, Block& block)
+{
+ if (block.original_y != -1) block.original_y = height - block.original_y - block.get_bbox().get_height();
+}
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_SUPERTUX_FLIP_LEVEL_TRANSFORMER_HPP
+#define HEADER_SUPERTUX_SUPERTUX_FLIP_LEVEL_TRANSFORMER_HPP
+
+#include "supertux/level_transformer.hpp"
+
+class TileMap;
+class BadGuy;
+class SpawnPoint;
+class MovingObject;
+class Platform;
+class Block;
+
+/** Vertically or horizontally flip a level */
+class FlipLevelTransformer : public LevelTransformer
+{
+public:
+ virtual void transform_sector(Sector* sector);
+
+private:
+ void transform_tilemap(TileMap* tilemap);
+ void transform_moving_object(float height, MovingObject* object);
+ void transform_badguy(float height, BadGuy* badguy);
+ void transform_spawnpoint(float height, SpawnPoint* spawnpoint);
+ void transform_platform(float height, Platform& platform);
+ void transform_block(float height, Block& block);
+};
+
+#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include "supertux/game_object.hpp"
+#include "supertux/object_remove_listener.hpp"
+
+GameObject::GameObject() :
+ wants_to_die(false),
+ remove_listeners(NULL)
+{
+}
+
+GameObject::GameObject(const GameObject& rhs) :
+ wants_to_die(rhs.wants_to_die),
+ remove_listeners(NULL)
+{
+}
+
+GameObject::~GameObject()
+{
+ // call remove listeners (and remove them from the list)
+ RemoveListenerListEntry* entry = remove_listeners;
+ while(entry != NULL) {
+ RemoveListenerListEntry* next = entry->next;
+ entry->listener->object_removed(this);
+ delete entry;
+ entry = next;
+ }
+}
+
+void
+GameObject::add_remove_listener(ObjectRemoveListener* listener)
+{
+ RemoveListenerListEntry* entry = new RemoveListenerListEntry();
+ entry->next = remove_listeners;
+ entry->listener = listener;
+ remove_listeners = entry;
+}
+
+void
+GameObject::del_remove_listener(ObjectRemoveListener* listener)
+{
+ RemoveListenerListEntry* entry = remove_listeners;
+ if (entry->listener == listener) {
+ remove_listeners = entry->next;
+ delete entry;
+ return;
+ }
+ RemoveListenerListEntry* next = entry->next;
+ while(next != NULL) {
+ if (next->listener == listener) {
+ entry->next = next->next;
+ delete next;
+ break;
+ }
+ entry = next;
+ next = next->next;
+ }
+}
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_SUPERTUX_GAME_OBJECT_HPP
+#define HEADER_SUPERTUX_SUPERTUX_GAME_OBJECT_HPP
+
+#include <string>
+
+#include "util/refcounter.hpp"
+
+class DrawingContext;
+class ObjectRemoveListener;
+
+/**
+ * Base class for all the things that make up Levels' Sectors.
+ *
+ * Each sector of a level will hold a list of active GameObject while the
+ * game is played.
+ *
+ * This class is responsible for:
+ * - Updating and Drawing the object. This should happen in the update() and
+ * draw() functions. Both are called once per frame.
+ * - Providing a safe way to remove the object by calling the remove_me
+ * functions.
+ */
+class GameObject : public RefCounter
+{
+public:
+ GameObject();
+ GameObject(const GameObject& rhs);
+ virtual ~GameObject();
+
+ /** This function is called once per frame and allows the object to update
+ * it's state. The elapsed_time is the time since the last frame in
+ * seconds and should be the base for all timed calculations (don't use
+ * SDL_GetTicks directly as this will fail in pause mode)
+ */
+ virtual void update(float elapsed_time) = 0;
+
+ /** The GameObject should draw itself onto the provided DrawingContext if this
+ * function is called.
+ */
+ virtual void draw(DrawingContext& context) = 0;
+
+ /** returns true if the object is not scheduled to be removed yet */
+ bool is_valid() const
+ {
+ return !wants_to_die;
+ }
+
+ /** schedules this object to be removed at the end of the frame */
+ void remove_me()
+ {
+ wants_to_die = true;
+ }
+
+ /** registers a remove listener which will be called if the object
+ * gets removed/destroyed
+ */
+ void add_remove_listener(ObjectRemoveListener* listener);
+
+ /**
+ * unregisters a remove listener, so it will no longer be called if the object
+ * gets removed/destroyed
+ */
+ void del_remove_listener(ObjectRemoveListener* listener);
+
+ const std::string& get_name() const
+ {
+ return name;
+ }
+
+private:
+ /** this flag indicates if the object should be removed at the end of the
+ * frame
+ */
+ bool wants_to_die;
+
+ struct RemoveListenerListEntry
+ {
+ RemoveListenerListEntry* next;
+ ObjectRemoveListener* listener;
+ };
+ RemoveListenerListEntry* remove_listeners;
+
+protected:
+ /**
+ * a name for the gameobject, this is mostly a hint for scripts and for
+ * debugging, don't rely on names being set or being unique
+ */
+ std::string name;
+
+private:
+ GameObject& operator=(const GameObject&);
+};
+
+#endif /*SUPERTUX_GAMEOBJECT_H*/
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include "supertux/game_session.hpp"
+
+#include <float.h>
+#include <fstream>
+
+#include "audio/sound_manager.hpp"
+#include "control/joystickkeyboardcontroller.hpp"
+#include "gui/menu.hpp"
+#include "math/random_generator.hpp"
+#include "object/camera.hpp"
+#include "object/endsequence_fireworks.hpp"
+#include "object/endsequence_walkleft.hpp"
+#include "object/endsequence_walkright.hpp"
+#include "object/level_time.hpp"
+#include "object/player.hpp"
+#include "scripting/squirrel_util.hpp"
+#include "supertux/gameconfig.hpp"
+#include "supertux/levelintro.hpp"
+#include "supertux/main.hpp"
+#include "supertux/mainloop.hpp"
+#include "supertux/options_menu.hpp"
+#include "supertux/sector.hpp"
+#include "util/file_system.hpp"
+#include "util/gettext.hpp"
+#include "worldmap/worldmap.hpp"
+
+enum GameMenuIDs {
+ MNID_CONTINUE,
+ MNID_ABORTLEVEL
+};
+
+GameSession::GameSession(const std::string& levelfile_, Statistics* statistics) :
+ level(0),
+ currentsector(0),
+ end_sequence(0),
+ levelfile(levelfile_),
+ best_level_statistics(statistics),
+ capture_demo_stream(0),
+ playback_demo_stream(0),
+ demo_controller(0),
+ play_time(0),
+ edit_mode(false),
+ levelintro_shown(false)
+{
+ currentsector = NULL;
+
+ game_pause = false;
+ speed_before_pause = g_main_loop->get_speed();
+
+ statistics_backdrop.reset(new Surface("images/engine/menu/score-backdrop.png"));
+
+ restart_level();
+
+ game_menu.reset(new Menu());
+ game_menu->add_label(level->name);
+ game_menu->add_hl();
+ game_menu->add_entry(MNID_CONTINUE, _("Continue"));
+ game_menu->add_submenu(_("Options"), get_options_menu());
+ game_menu->add_hl();
+ game_menu->add_entry(MNID_ABORTLEVEL, _("Abort Level"));
+}
+
+void
+GameSession::restart_level()
+{
+
+ if (edit_mode) {
+ force_ghost_mode();
+ return;
+ }
+
+ game_pause = false;
+ end_sequence = 0;
+
+ g_main_controller->reset();
+
+ currentsector = 0;
+
+ level.reset(new Level);
+ try {
+ level->load(levelfile);
+ level->stats.total_coins = level->get_total_coins();
+ level->stats.total_badguys = level->get_total_badguys();
+ level->stats.total_secrets = level->get_total_secrets();
+ level->stats.reset();
+
+ if(reset_sector != "") {
+ currentsector = level->get_sector(reset_sector);
+ if(!currentsector) {
+ std::stringstream msg;
+ msg << "Couldn't find sector '" << reset_sector << "' for resetting tux.";
+ throw std::runtime_error(msg.str());
+ }
+ level->stats.declare_invalid();
+ currentsector->activate(reset_pos);
+ } else {
+ currentsector = level->get_sector("main");
+ if(!currentsector)
+ throw std::runtime_error("Couldn't find main sector");
+ play_time = 0;
+ currentsector->activate("main");
+ }
+ } catch(std::exception& e) {
+ log_fatal << "Couldn't start level: " << e.what() << std::endl;
+ g_main_loop->exit_screen();
+ }
+
+ sound_manager->stop_music();
+ currentsector->play_music(LEVEL_MUSIC);
+
+ if(capture_file != "") {
+ int newSeed=0; // next run uses a new seed
+ while (newSeed == 0) // which is the next non-zero random num.
+ newSeed = systemRandom.rand();
+ g_config->random_seed = systemRandom.srand(newSeed);
+ log_info << "Next run uses random seed " << g_config->random_seed <<std::endl;
+ record_demo(capture_file);
+ }
+}
+
+GameSession::~GameSession()
+{
+ delete capture_demo_stream;
+ delete playback_demo_stream;
+ delete demo_controller;
+ free_options_menu();
+}
+
+void
+GameSession::record_demo(const std::string& filename)
+{
+ delete capture_demo_stream;
+
+ capture_demo_stream = new std::ofstream(filename.c_str());
+ if(!capture_demo_stream->good()) {
+ std::stringstream msg;
+ msg << "Couldn't open demo file '" << filename << "' for writing.";
+ throw std::runtime_error(msg.str());
+ }
+ capture_file = filename;
+
+ char buf[30]; // save the seed in the demo file
+ snprintf(buf, sizeof(buf), "random_seed=%10d", g_config->random_seed);
+ for (int i=0; i==0 || buf[i-1]; i++)
+ capture_demo_stream->put(buf[i]);
+}
+
+int
+GameSession::get_demo_random_seed(const std::string& filename)
+{
+ std::istream* test_stream = new std::ifstream(filename.c_str());
+ if(test_stream->good()) {
+ char buf[30]; // recall the seed from the demo file
+ int seed;
+ for (int i=0; i<30 && (i==0 || buf[i-1]); i++)
+ test_stream->get(buf[i]);
+ if (sscanf(buf, "random_seed=%10d", &seed) == 1) {
+ log_info << "Random seed " << seed << " from demo file" << std::endl;
+ return seed;
+ }
+ else
+ log_info << "Demo file contains no random number" << std::endl;
+ }
+ return 0;
+}
+
+void
+GameSession::play_demo(const std::string& filename)
+{
+ delete playback_demo_stream;
+ delete demo_controller;
+
+ playback_demo_stream = new std::ifstream(filename.c_str());
+ if(!playback_demo_stream->good()) {
+ std::stringstream msg;
+ msg << "Couldn't open demo file '" << filename << "' for reading.";
+ throw std::runtime_error(msg.str());
+ }
+
+ Player& tux = *currentsector->player;
+ demo_controller = new CodeController();
+ tux.set_controller(demo_controller);
+
+ // skip over random seed, if it exists in the file
+ char buf[30]; // ascii decimal seed
+ int seed;
+ for (int i=0; i<30 && (i==0 || buf[i-1]); i++)
+ playback_demo_stream->get(buf[i]);
+ if (sscanf(buf, "random_seed=%010d", &seed) != 1)
+ playback_demo_stream->seekg(0); // old style w/o seed, restart at beg
+}
+
+void
+GameSession::on_escape_press()
+{
+ if(currentsector->player->is_dying() || end_sequence)
+ {
+ // Let the timers run out, we fast-forward them to force past a sequence
+ if (end_sequence)
+ end_sequence->stop();
+
+ currentsector->player->dying_timer.start(FLT_EPSILON);
+ return; // don't let the player open the menu, when he is dying
+ }
+
+ if(level->on_menukey_script != "") {
+ std::istringstream in(level->on_menukey_script);
+ run_script(in, "OnMenuKeyScript");
+ } else {
+ toggle_pause();
+ }
+}
+
+void
+GameSession::toggle_pause()
+{
+ // pause
+ if(!game_pause) {
+ speed_before_pause = g_main_loop->get_speed();
+ g_main_loop->set_speed(0);
+ Menu::set_current(game_menu.get());
+ game_menu->set_active_item(MNID_CONTINUE);
+ game_pause = true;
+ }
+
+ // unpause is done in update() after the menu is processed
+}
+
+void
+GameSession::set_editmode(bool edit_mode)
+{
+ if (this->edit_mode == edit_mode) return;
+ this->edit_mode = edit_mode;
+
+ currentsector->get_players()[0]->set_edit_mode(edit_mode);
+
+ if (edit_mode) {
+
+ // entering edit mode
+
+ } else {
+
+ // leaving edit mode
+ restart_level();
+
+ }
+}
+
+void
+GameSession::force_ghost_mode()
+{
+ currentsector->get_players()[0]->set_ghost_mode(true);
+}
+
+HSQUIRRELVM
+GameSession::run_script(std::istream& in, const std::string& sourcename)
+{
+ using namespace Scripting;
+
+ // garbage collect thread list
+ for(ScriptList::iterator i = scripts.begin();
+ i != scripts.end(); ) {
+ HSQOBJECT& object = *i;
+ HSQUIRRELVM vm = object_to_vm(object);
+
+ if(sq_getvmstate(vm) != SQ_VMSTATE_SUSPENDED) {
+ sq_release(global_vm, &object);
+ i = scripts.erase(i);
+ continue;
+ }
+
+ ++i;
+ }
+
+ HSQOBJECT object = create_thread(global_vm);
+ scripts.push_back(object);
+
+ HSQUIRRELVM vm = object_to_vm(object);
+
+ compile_and_run(vm, in, sourcename);
+
+ return vm;
+}
+
+void
+GameSession::process_events()
+{
+ // end of pause mode?
+ // XXX this looks like a fail-safe to unpause the game if there's no menu
+ // XXX having it enabled causes some unexpected problems
+ // XXX hopefully disabling it won't...
+ /*
+ if(!Menu::current() && game_pause) {
+ game_pause = false;
+ }
+ */
+
+ // playback a demo?
+ if(playback_demo_stream != 0) {
+ demo_controller->update();
+ char left = false;
+ char right = false;
+ char up = false;
+ char down = false;
+ char jump = false;
+ char action = false;
+ playback_demo_stream->get(left);
+ playback_demo_stream->get(right);
+ playback_demo_stream->get(up);
+ playback_demo_stream->get(down);
+ playback_demo_stream->get(jump);
+ playback_demo_stream->get(action);
+ demo_controller->press(Controller::LEFT, left);
+ demo_controller->press(Controller::RIGHT, right);
+ demo_controller->press(Controller::UP, up);
+ demo_controller->press(Controller::DOWN, down);
+ demo_controller->press(Controller::JUMP, jump);
+ demo_controller->press(Controller::ACTION, action);
+ }
+
+ // save input for demo?
+ if(capture_demo_stream != 0) {
+ capture_demo_stream ->put(g_main_controller->hold(Controller::LEFT));
+ capture_demo_stream ->put(g_main_controller->hold(Controller::RIGHT));
+ capture_demo_stream ->put(g_main_controller->hold(Controller::UP));
+ capture_demo_stream ->put(g_main_controller->hold(Controller::DOWN));
+ capture_demo_stream ->put(g_main_controller->hold(Controller::JUMP));
+ capture_demo_stream ->put(g_main_controller->hold(Controller::ACTION));
+ }
+}
+
+void
+GameSession::check_end_conditions()
+{
+ Player* tux = currentsector->player;
+
+ /* End of level? */
+ if(end_sequence && end_sequence->is_done()) {
+ finish(true);
+ } else if (!end_sequence && tux->is_dead()) {
+ restart_level();
+ }
+}
+
+void
+GameSession::draw(DrawingContext& context)
+{
+ currentsector->draw(context);
+ drawstatus(context);
+
+ if(game_pause)
+ draw_pause(context);
+}
+
+void
+GameSession::draw_pause(DrawingContext& context)
+{
+ context.draw_filled_rect(
+ Vector(0,0), Vector(SCREEN_WIDTH, SCREEN_HEIGHT),
+ Color(0.0f, 0.0f, 0.0f, .25f), LAYER_FOREGROUND1);
+}
+
+void
+GameSession::process_menu()
+{
+ Menu* menu = Menu::current();
+ if(menu) {
+ if(menu == game_menu.get()) {
+ switch (game_menu->check()) {
+ case MNID_CONTINUE:
+ Menu::set_current(0);
+ toggle_pause();
+ break;
+ case MNID_ABORTLEVEL:
+ Menu::set_current(0);
+ g_main_loop->exit_screen();
+ break;
+ }
+ }
+ }
+}
+
+void
+GameSession::setup()
+{
+ if(currentsector != Sector::current()) {
+ currentsector->activate(currentsector->player->get_pos());
+ }
+ currentsector->play_music(LEVEL_MUSIC);
+
+ // Eat unneeded events
+ SDL_Event event;
+ while(SDL_PollEvent(&event))
+ {}
+
+ if (!levelintro_shown) {
+ levelintro_shown = true;
+ g_main_loop->push_screen(new LevelIntro(level.get(), best_level_statistics));
+ }
+}
+
+void
+GameSession::update(float elapsed_time)
+{
+ // handle controller
+ if(g_main_controller->pressed(Controller::PAUSE_MENU))
+ on_escape_press();
+
+ process_events();
+ process_menu();
+
+ // Unpause the game if the menu has been closed
+ if (game_pause && !Menu::current()) {
+ g_main_loop->set_speed(speed_before_pause);
+ game_pause = false;
+ }
+
+ check_end_conditions();
+
+ // respawning in new sector?
+ if(newsector != "" && newspawnpoint != "") {
+ Sector* sector = level->get_sector(newsector);
+ if(sector == 0) {
+ log_warning << "Sector '" << newsector << "' not found" << std::endl;
+ sector = level->get_sector("main");
+ }
+ sector->activate(newspawnpoint);
+ sector->play_music(LEVEL_MUSIC);
+ currentsector = sector;
+ //Keep persistent across sectors
+ if(edit_mode)
+ currentsector->get_players()[0]->set_edit_mode(edit_mode);
+ newsector = "";
+ newspawnpoint = "";
+ }
+
+ // Update the world state and all objects in the world
+ if(!game_pause) {
+ // Update the world
+ if (!end_sequence) {
+ play_time += elapsed_time; //TODO: make sure we don't count cutscene time
+ level->stats.time = play_time;
+ currentsector->update(elapsed_time);
+ } else {
+ if (!end_sequence->is_tux_stopped()) {
+ currentsector->update(elapsed_time);
+ } else {
+ end_sequence->update(elapsed_time);
+ }
+ }
+ }
+
+ // update sounds
+ if (currentsector && currentsector->camera) sound_manager->set_listener_position(currentsector->camera->get_center());
+
+ /* Handle music: */
+ if (end_sequence)
+ return;
+
+ if(currentsector->player->invincible_timer.started()) {
+ if(currentsector->player->invincible_timer.get_timeleft() <=
+ TUX_INVINCIBLE_TIME_WARNING) {
+ currentsector->play_music(HERRING_WARNING_MUSIC);
+ } else {
+ currentsector->play_music(HERRING_MUSIC);
+ }
+ } else if(currentsector->get_music_type() != LEVEL_MUSIC) {
+ currentsector->play_music(LEVEL_MUSIC);
+ }
+}
+
+void
+GameSession::finish(bool win)
+{
+ using namespace WorldMapNS;
+
+ if (edit_mode) {
+ force_ghost_mode();
+ return;
+ }
+
+ if(win) {
+ if(WorldMap::current())
+ WorldMap::current()->finished_level(level.get());
+ }
+
+ g_main_loop->exit_screen();
+}
+
+void
+GameSession::respawn(const std::string& sector, const std::string& spawnpoint)
+{
+ newsector = sector;
+ newspawnpoint = spawnpoint;
+}
+
+void
+GameSession::set_reset_point(const std::string& sector, const Vector& pos)
+{
+ reset_sector = sector;
+ reset_pos = pos;
+}
+
+std::string
+GameSession::get_working_directory()
+{
+ return FileSystem::dirname(levelfile);
+}
+
+void
+GameSession::start_sequence(const std::string& sequencename)
+{
+ // do not play sequences when in edit mode
+ if (edit_mode) {
+ force_ghost_mode();
+ return;
+ }
+
+ // handle special "stoptux" sequence
+ if (sequencename == "stoptux") {
+ if (!end_sequence) {
+ log_warning << "Final target reached without an active end sequence" << std::endl;
+ this->start_sequence("endsequence");
+ }
+ if (end_sequence) end_sequence->stop_tux();
+ return;
+ }
+
+ // abort if a sequence is already playing
+ if (end_sequence)
+ return;
+
+ if (sequencename == "endsequence") {
+ if (currentsector->get_players()[0]->get_physic().get_velocity_x() < 0) {
+ end_sequence = new EndSequenceWalkLeft();
+ } else {
+ end_sequence = new EndSequenceWalkRight();
+ }
+ } else if (sequencename == "fireworks") {
+ end_sequence = new EndSequenceFireworks();
+ } else {
+ log_warning << "Unknown sequence '" << sequencename << "'. Ignoring." << std::endl;
+ return;
+ }
+
+ /* slow down the game for end-sequence */
+ g_main_loop->set_speed(0.5f);
+
+ currentsector->add_object(end_sequence);
+ end_sequence->start();
+
+ sound_manager->play_music("music/leveldone.music", false);
+ currentsector->player->invincible_timer.start(10000.0f);
+
+ // Stop all clocks.
+ for(std::vector<GameObject*>::iterator i = currentsector->gameobjects.begin();
+ i != currentsector->gameobjects.end(); ++i)
+ {
+ GameObject* obj = *i;
+
+ LevelTime* lt = dynamic_cast<LevelTime*> (obj);
+ if(lt)
+ lt->stop();
+ }
+}
+
+/* (Status): */
+void
+GameSession::drawstatus(DrawingContext& context)
+{
+ player_status->draw(context);
+
+ // draw level stats while end_sequence is running
+ if (end_sequence) {
+ level->stats.draw_endseq_panel(context, best_level_statistics, statistics_backdrop.get());
+ }
+}
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_SUPERTUX_GAME_SESSION_HPP
+#define HEADER_SUPERTUX_SUPERTUX_GAME_SESSION_HPP
+
+#include <memory>
+#include <vector>
+#include <squirrel.h>
+
+#include "object/endsequence.hpp"
+#include "supertux/screen.hpp"
+#include "util/currenton.hpp"
+#include "video/surface.hpp"
+
+class Level;
+class Sector;
+class Statistics;
+class DrawingContext;
+class CodeController;
+class Menu;
+
+/**
+ * Screen that runs a Level, where Players run and jump through Sectors.
+ */
+class GameSession : public Screen,
+ public Currenton<GameSession>
+{
+public:
+ GameSession(const std::string& levelfile, Statistics* statistics = NULL);
+ ~GameSession();
+
+ void record_demo(const std::string& filename);
+ int get_demo_random_seed(const std::string& filename);
+ void play_demo(const std::string& filename);
+
+ void draw(DrawingContext& context);
+ void update(float frame_ratio);
+ void setup();
+
+ /// ends the current level
+ void finish(bool win = true);
+ void respawn(const std::string& sectorname, const std::string& spawnpointname);
+ void set_reset_point(const std::string& sectorname, const Vector& pos);
+ std::string get_reset_point_sectorname()
+ { return reset_sector; }
+
+ Vector get_reset_point_pos()
+ { return reset_pos; }
+
+ Sector* get_current_sector()
+ { return currentsector; }
+
+ Level* get_current_level()
+ { return level.get(); }
+
+ void start_sequence(const std::string& sequencename);
+
+ /**
+ * returns the "working directory" usually this is the directory where the
+ * currently played level resides. This is used when locating additional
+ * resources for the current level/world
+ */
+ std::string get_working_directory();
+ void restart_level();
+
+ void toggle_pause();
+
+ /**
+ * Enters or leaves level editor mode
+ */
+ void set_editmode(bool edit_mode = true);
+
+ /**
+ * Forces all Players to enter ghost mode
+ */
+ void force_ghost_mode();
+
+private:
+ void check_end_conditions();
+ void process_events();
+ void capture_demo_step();
+
+ void drawstatus(DrawingContext& context);
+ void draw_pause(DrawingContext& context);
+
+ HSQUIRRELVM run_script(std::istream& in, const std::string& sourcename);
+ void on_escape_press();
+ void process_menu();
+
+ std::auto_ptr<Level> level;
+ std::auto_ptr<Surface> statistics_backdrop;
+
+ // scripts
+ typedef std::vector<HSQOBJECT> ScriptList;
+ ScriptList scripts;
+
+ Sector* currentsector;
+
+ int levelnb;
+ int pause_menu_frame;
+
+ EndSequence* end_sequence;
+
+ bool game_pause;
+ float speed_before_pause;
+
+ std::string levelfile;
+
+ // reset point (the point where tux respawns if he dies)
+ std::string reset_sector;
+ Vector reset_pos;
+
+ // the sector and spawnpoint we should spawn after this frame
+ std::string newsector;
+ std::string newspawnpoint;
+
+ Statistics* best_level_statistics;
+
+ std::ostream* capture_demo_stream;
+ std::string capture_file;
+ std::istream* playback_demo_stream;
+ CodeController* demo_controller;
+
+ std::auto_ptr<Menu> game_menu;
+
+ float play_time; /**< total time in seconds that this session ran interactively */
+
+ bool edit_mode; /**< true if GameSession runs in level editor mode */
+ bool levelintro_shown; /**< true if the LevelIntro screen was already shown */
+
+private:
+ GameSession(const GameSession&);
+ GameSession& operator=(const GameSession&);
+};
+
+#endif /*SUPERTUX_GAMELOOP_H*/
+
+/* EOF */
--- /dev/null
+// SuperTux - A Jump'n Run
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include "supertux/gameconfig.hpp"
+
+#include <stdexcept>
+
+#include "addon/addon_manager.hpp"
+#include "control/joystickkeyboardcontroller.hpp"
+#include "lisp/lisp.hpp"
+#include "lisp/writer.hpp"
+#include "lisp/parser.hpp"
+#include "supertux/main.hpp"
+
+Config* g_config = 0;
+
+Config::Config()
+{
+ profile = 1;
+ use_fullscreen = false;
+ video = AUTO_VIDEO;
+ try_vsync = true;
+ show_fps = false;
+ sound_enabled = true;
+ music_enabled = true;
+ console_enabled = false;
+ random_seed = 0; // set by time(), by default (unless in config)
+
+ window_width = 800;
+ window_height = 600;
+
+ fullscreen_width = 800;
+ fullscreen_height = 600;
+
+ magnification = 1.0f;
+
+ aspect_width = 0; // auto detect
+ aspect_height = 0;
+
+ enable_script_debugger = false;
+
+ locale = ""; // autodetect
+}
+
+Config::~Config()
+{}
+
+void
+Config::load()
+{
+ lisp::Parser parser;
+ const lisp::Lisp* root = parser.parse("config");
+
+ const lisp::Lisp* config_lisp = root->get_lisp("supertux-config");
+ if(!config_lisp)
+ throw std::runtime_error("File is not a supertux-config file");
+
+ config_lisp->get("show_fps", show_fps);
+ config_lisp->get("console", console_enabled);
+ config_lisp->get("locale", locale);
+ config_lisp->get("random_seed", random_seed);
+
+ const lisp::Lisp* config_video_lisp = config_lisp->get_lisp("video");
+ if(config_video_lisp) {
+ config_video_lisp->get("fullscreen", use_fullscreen);
+ std::string video_string;
+ config_video_lisp->get("video", video_string);
+ video = get_video_system(video_string);
+ config_video_lisp->get("vsync", try_vsync);
+
+ config_video_lisp->get("fullscreen_width", fullscreen_width);
+ config_video_lisp->get("fullscreen_height", fullscreen_height);
+
+ config_video_lisp->get("window_width", window_width);
+ config_video_lisp->get("window_height", window_height);
+
+ config_video_lisp->get("aspect_width", aspect_width);
+ config_video_lisp->get("aspect_height", aspect_height);
+ }
+
+ const lisp::Lisp* config_audio_lisp = config_lisp->get_lisp("audio");
+ if(config_audio_lisp) {
+ config_audio_lisp->get("sound_enabled", sound_enabled);
+ config_audio_lisp->get("music_enabled", music_enabled);
+ }
+
+ const lisp::Lisp* config_control_lisp = config_lisp->get_lisp("control");
+ if(config_control_lisp && g_main_controller) {
+ g_main_controller->read(*config_control_lisp);
+ }
+
+ const lisp::Lisp* config_addons_lisp = config_lisp->get_lisp("addons");
+ if(config_addons_lisp) {
+ AddonManager::get_instance().read(*config_addons_lisp);
+ }
+}
+
+void
+Config::save()
+{
+ lisp::Writer writer("config");
+
+ writer.start_list("supertux-config");
+
+ writer.write("show_fps", show_fps);
+ writer.write("console", console_enabled);
+ writer.write("locale", locale);
+
+ writer.start_list("video");
+ writer.write("fullscreen", use_fullscreen);
+ writer.write("video", get_video_string(video));
+ writer.write("vsync", try_vsync);
+
+ writer.write("fullscreen_width", fullscreen_width);
+ writer.write("fullscreen_height", fullscreen_height);
+
+ writer.write("window_width", window_width);
+ writer.write("window_height", window_height);
+
+ writer.write("aspect_width", aspect_width);
+ writer.write("aspect_height", aspect_height);
+
+ writer.end_list("video");
+
+ writer.start_list("audio");
+ writer.write("sound_enabled", sound_enabled);
+ writer.write("music_enabled", music_enabled);
+ writer.end_list("audio");
+
+ if(g_main_controller) {
+ writer.start_list("control");
+ g_main_controller->write(writer);
+ writer.end_list("control");
+ }
+
+ writer.start_list("addons");
+ AddonManager::get_instance().write(writer);
+ writer.end_list("addons");
+
+ writer.end_list("supertux-config");
+}
+
+/* EOF */
--- /dev/null
+// SuperTux=
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_SUPERTUX_GAMECONFIG_HPP
+#define HEADER_SUPERTUX_SUPERTUX_GAMECONFIG_HPP
+
+#include "video/video_systems.hpp"
+
+class Config
+{
+public:
+ Config();
+ ~Config();
+
+ void load();
+ void save();
+
+ int profile;
+
+ // the width/height to be used to display the game in fullscreen
+ int fullscreen_width;
+ int fullscreen_height;
+
+ // the width/height of the window managers window
+ int window_width;
+ int window_height;
+
+ // the aspect ratio
+ int aspect_width;
+ int aspect_height;
+
+ float magnification;
+
+ bool use_fullscreen;
+ VideoSystem video;
+ bool try_vsync;
+ bool show_fps;
+ bool sound_enabled;
+ bool music_enabled;
+ bool console_enabled;
+
+ int random_seed; // initial random seed. 0 ==> set from time()
+
+ /** this variable is set if supertux should start in a specific level */
+ std::string start_level;
+ bool enable_script_debugger;
+ std::string start_demo;
+ std::string record_demo;
+
+ std::string locale; /**< force SuperTux language to this locale, e.g. "de". A file "data/locale/xx.po" must exist for this to work. An empty string means autodetect. */
+};
+
+extern Config* g_config;
+
+#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include "supertux/level.hpp"
+
+#include "lisp/list_iterator.hpp"
+#include "lisp/parser.hpp"
+#include "object/block.hpp"
+#include "object/coin.hpp"
+#include "supertux/sector.hpp"
+#include "supertux/tile_manager.hpp"
+#include "supertux/tile_set.hpp"
+#include "trigger/secretarea_trigger.hpp"
+
+using namespace std;
+
+Level::Level() :
+ name("noname"),
+ author("Mr. X"),
+ tileset(NULL),
+ free_tileset(false)
+{
+}
+
+Level::~Level()
+{
+ for(Sectors::iterator i = sectors.begin(); i != sectors.end(); ++i)
+ delete *i;
+ if(free_tileset)
+ delete tileset;
+}
+
+void
+Level::load(const std::string& filepath)
+{
+ try {
+ filename = filepath;
+ lisp::Parser parser;
+ const lisp::Lisp* root = parser.parse(filepath);
+
+ const lisp::Lisp* level = root->get_lisp("supertux-level");
+ if(!level)
+ throw std::runtime_error("file is not a supertux-level file.");
+
+ int version = 1;
+ level->get("version", version);
+ if(version == 1) {
+ log_info << "level uses old format: version 1" << std::endl;
+ tileset = tile_manager->get_tileset("images/tiles.strf");
+ load_old_format(*level);
+ return;
+ }
+
+ const lisp::Lisp* tilesets_lisp = level->get_lisp("tilesets");
+ if(tilesets_lisp != NULL) {
+ tileset = tile_manager->parse_tileset_definition(*tilesets_lisp);
+ free_tileset = true;
+ }
+ std::string tileset_name;
+ if(level->get("tileset", tileset_name)) {
+ if(tileset != NULL) {
+ log_warning << "multiple tilesets specified in level" << std::endl;
+ } else {
+ tileset = tile_manager->get_tileset(tileset_name);
+ }
+ }
+ /* load default tileset */
+ if(tileset == NULL) {
+ tileset = tile_manager->get_tileset("images/tiles.strf");
+ }
+ current_tileset = tileset;
+
+ contact = "";
+ license = "";
+
+ lisp::ListIterator iter(level);
+ while(iter.next()) {
+ const std::string& token = iter.item();
+ if(token == "version") {
+ iter.value()->get(version);
+ if(version > 2) {
+ log_warning << "level format newer than application" << std::endl;
+ }
+ } else if(token == "tileset" || token == "tilesets") {
+ continue;
+ } else if(token == "name") {
+ iter.value()->get(name);
+ } else if(token == "author") {
+ iter.value()->get(author);
+ } else if(token == "contact") {
+ iter.value()->get(contact);
+ } else if(token == "license") {
+ iter.value()->get(license);
+ } else if(token == "on-menukey-script") {
+ iter.value()->get(on_menukey_script);
+ } else if(token == "sector") {
+ Sector* sector = new Sector(this);
+ sector->parse(*(iter.lisp()));
+ add_sector(sector);
+ } else {
+ log_warning << "Unknown token '" << token << "' in level file" << std::endl;
+ }
+ }
+
+ if (license == "") {
+ log_warning << "The level author did not specify a license for this level. You might not be allowed to share it." << std::endl;
+
+ }
+ } catch(std::exception& e) {
+ std::stringstream msg;
+ msg << "Problem when reading level '" << filepath << "': " << e.what();
+ throw std::runtime_error(msg.str());
+ }
+
+ current_tileset = NULL;
+}
+
+void
+Level::load_old_format(const Reader& reader)
+{
+ reader.get("name", name);
+ reader.get("author", author);
+
+ Sector* sector = new Sector(this);
+ sector->parse_old_format(reader);
+ add_sector(sector);
+}
+
+void
+Level::add_sector(Sector* sector)
+{
+ Sector* test = get_sector(sector->get_name());
+ if(test != 0) {
+ throw std::runtime_error("Trying to add 2 sectors with same name");
+ }
+ sectors.push_back(sector);
+}
+
+Sector*
+Level::get_sector(const std::string& name)
+{
+ for(Sectors::iterator i = sectors.begin(); i != sectors.end(); ++i) {
+ Sector* sector = *i;
+ if(sector->get_name() == name)
+ return sector;
+ }
+
+ return 0;
+}
+
+size_t
+Level::get_sector_count()
+{
+ return sectors.size();
+}
+
+Sector*
+Level::get_sector(size_t num)
+{
+ return sectors.at(num);
+}
+
+int
+Level::get_total_coins()
+{
+ int total_coins = 0;
+ for(Sectors::iterator i = sectors.begin(); i != sectors.end(); ++i) {
+ Sector* sector = *i;
+ for(Sector::GameObjects::iterator o = sector->gameobjects.begin();
+ o != sector->gameobjects.end(); ++o) {
+ Coin* coin = dynamic_cast<Coin*> (*o);
+ if(coin)
+ {
+ total_coins++;
+ continue;
+ }
+ BonusBlock *block = dynamic_cast<BonusBlock*> (*o);
+ if(block)
+ {
+ if (block->contents == BonusBlock::CONTENT_COIN)
+ {
+ total_coins++;
+ continue;
+ }
+#if 0
+ // FIXME: do we want this? q.v. src/object/oneup.cpp
+ else if (block->contents == BonusBlock::CONTENT_1UP)
+ {
+ total_coins += 100;
+ continue;
+ }
+#endif
+ }
+ }
+ }
+ return total_coins;
+}
+
+int
+Level::get_total_badguys()
+{
+ int total_badguys = 0;
+ for(Sectors::iterator i = sectors.begin(); i != sectors.end(); ++i)
+ total_badguys += (*i)->get_total_badguys();
+ return total_badguys;
+}
+
+int
+Level::get_total_secrets()
+{
+ int total_secrets = 0;
+ for(Sectors::iterator i = sectors.begin(); i != sectors.end(); ++i)
+ total_secrets += (*i)->get_total_count<SecretAreaTrigger>();
+ return total_secrets;
+}
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_SUPERTUX_LEVEL_HPP
+#define HEADER_SUPERTUX_SUPERTUX_LEVEL_HPP
+
+#include "supertux/statistics.hpp"
+#include "util/reader_fwd.hpp"
+
+class TileSet;
+class Sector;
+
+/**
+ * Represents a collection of Sectors running in a single GameSession.
+ *
+ * Each Sector in turn contains GameObjects, e.g. Badguys and Players.
+ */
+class Level
+{
+public:
+ typedef std::vector<Sector*> Sectors;
+
+ std::string name;
+ std::string author;
+ std::string contact;
+ std::string license;
+ std::string filename;
+ std::string on_menukey_script;
+ Sectors sectors;
+ Statistics stats;
+ TileSet *tileset;
+ bool free_tileset;
+
+public:
+ Level();
+ ~Level();
+
+ // loads a levelfile
+ void load(const std::string& filename);
+
+ const std::string& get_name() const
+ { return name; }
+
+ const std::string& get_author() const
+ { return author; }
+
+ void add_sector(Sector* sector);
+
+ Sector* get_sector(const std::string& name);
+
+ size_t get_sector_count();
+ Sector* get_sector(size_t num);
+
+ const TileSet *get_tileset() const
+ { return tileset; }
+
+ int get_total_coins();
+ int get_total_badguys();
+ int get_total_secrets();
+
+private:
+ void load_old_format(const Reader& reader);
+
+private:
+ Level(const Level&);
+ Level& operator=(const Level&);
+};
+
+#endif /*SUPERTUX_LEVEL_H*/
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include "supertux/level.hpp"
+#include "supertux/level_transformer.hpp"
+
+LevelTransformer::~LevelTransformer()
+{
+}
+
+void
+LevelTransformer::transform(Level* level)
+{
+ for(size_t i = 0; i < level->get_sector_count(); ++i) {
+ transform_sector(level->get_sector(i));
+ }
+}
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_SUPERTUX_LEVEL_TRANSFORMER_HPP
+#define HEADER_SUPERTUX_SUPERTUX_LEVEL_TRANSFORMER_HPP
+
+class Level;
+class Sector;
+
+/**
+ * This class is an abstract interface for algorithms that transform levels in
+ * some way before they are played.
+ */
+class LevelTransformer
+{
+public:
+ virtual ~LevelTransformer();
+
+ /** transform a complete Level, the standard implementation just calls
+ * transformSector on each sector in the level.
+ */
+ virtual void transform(Level* level);
+
+ virtual void transform_sector(Sector* sector) = 0;
+};
+
+#endif
+
+/* EOF */
--- /dev/null
+// SuperTux -- LevelIntro screen
+// Copyright (C) 2008 Christoph Sommer <christoph.sommer@2008.expires.deltadevelopment.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include "supertux/levelintro.hpp"
+
+#include "control/joystickkeyboardcontroller.hpp"
+#include "math/random_generator.hpp"
+#include "sprite/sprite_manager.hpp"
+#include "supertux/fadeout.hpp"
+#include "supertux/main.hpp"
+#include "supertux/mainloop.hpp"
+#include "supertux/resources.hpp"
+#include "util/gettext.hpp"
+
+LevelIntro::LevelIntro(const Level* level, const Statistics* best_level_statistics) :
+ level(level),
+ best_level_statistics(best_level_statistics),
+ player_sprite_py(0),
+ player_sprite_vy(0)
+{
+ player_sprite = sprite_manager->create("images/creatures/tux/tux.sprite");
+ player_sprite->set_action("small-walk-right");
+ player_sprite_jump_timer.start(systemRandom.randf(5,10));
+}
+
+LevelIntro::~LevelIntro()
+{
+}
+
+void
+LevelIntro::setup()
+{
+}
+
+void
+LevelIntro::update(float elapsed_time)
+{
+
+ // Check if it's time to exit the screen
+ if(g_main_controller->pressed(Controller::JUMP)
+ || g_main_controller->pressed(Controller::ACTION)
+ || g_main_controller->pressed(Controller::MENU_SELECT)
+ || g_main_controller->pressed(Controller::PAUSE_MENU)) {
+ g_main_loop->exit_screen(new FadeOut(0.1));
+ }
+
+ player_sprite_py += player_sprite_vy * elapsed_time;
+ player_sprite_vy += 1000 * elapsed_time;
+ if (player_sprite_py >= 0) {
+ player_sprite_py = 0;
+ player_sprite_vy = 0;
+ }
+ if (player_sprite_jump_timer.check()) {
+ player_sprite_vy = -300;
+ player_sprite_jump_timer.start(systemRandom.randf(2,3));
+ }
+
+}
+
+void
+LevelIntro::draw(DrawingContext& context)
+{
+ const Statistics& stats = level->stats;
+ int py = static_cast<int>(SCREEN_HEIGHT / 2 - normal_font->get_height() / 2);
+
+ context.draw_filled_rect(Vector(0, 0), Vector(SCREEN_WIDTH, SCREEN_HEIGHT), Color(0.0f, 0.0f, 0.0f, 1.0f), 0);
+
+ {
+ context.draw_center_text(normal_font, level->get_name(), Vector(0, py), LAYER_FOREGROUND1, LevelIntro::header_color);
+ py += static_cast<int>(normal_font->get_height());
+ }
+
+ std::string author = level->get_author();
+ if ((author != "") && (author != "SuperTux Team")) {
+ std::string author_text = std::string(_("contributed by ")) + author;
+ context.draw_center_text(small_font, author_text, Vector(0, py), LAYER_FOREGROUND1, LevelIntro::author_color);
+ py += static_cast<int>(small_font->get_height());
+ }
+
+ py += 32;
+
+ {
+ player_sprite->draw(context, Vector((SCREEN_WIDTH - player_sprite->get_current_hitbox_width()) / 2, py + player_sprite_py), LAYER_FOREGROUND1);
+ py += static_cast<int>(player_sprite->get_current_hitbox_height());
+ }
+
+ py += 32;
+
+ {
+ context.draw_center_text(normal_font, std::string("- ") + _("Best Level Statistics") + std::string(" -"), Vector(0, py), LAYER_FOREGROUND1, LevelIntro::stat_hdr_color);
+ py += static_cast<int>(normal_font->get_height());
+ }
+
+ {
+ std::stringstream ss;
+ ss << _("Coins") << ": " << Statistics::coins_to_string((best_level_statistics && (best_level_statistics->coins >= 0)) ? best_level_statistics->coins : 0, stats.total_coins);
+ context.draw_center_text(normal_font, ss.str(), Vector(0, py), LAYER_FOREGROUND1, LevelIntro::stat_color);
+ py += static_cast<int>(normal_font->get_height());
+ }
+
+ {
+ std::stringstream ss;
+ ss << _("Secrets") << ": " << Statistics::secrets_to_string((best_level_statistics && (best_level_statistics->coins >= 0)) ? best_level_statistics->secrets : 0, stats.total_secrets);
+ context.draw_center_text(normal_font, ss.str(), Vector(0, py), LAYER_FOREGROUND1,LevelIntro::stat_color);
+ py += static_cast<int>(normal_font->get_height());
+ }
+
+ {
+ std::stringstream ss;
+ ss << _("Time") << ": " << Statistics::time_to_string((best_level_statistics && (best_level_statistics->coins >= 0)) ? best_level_statistics->time : 0);
+ context.draw_center_text(normal_font, ss.str(), Vector(0, py), LAYER_FOREGROUND1,LevelIntro::stat_color);
+ py += static_cast<int>(normal_font->get_height());
+ }
+
+}
+
+/* EOF */
--- /dev/null
+// SuperTux -- LevelIntro screen
+// Copyright (C) 2008 Christoph Sommer <christoph.sommer@2008.expires.deltadevelopment.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_SUPERTUX_LEVELINTRO_HPP
+#define HEADER_SUPERTUX_SUPERTUX_LEVELINTRO_HPP
+
+#include "sprite/sprite.hpp"
+#include "supertux/level.hpp"
+#include "supertux/screen.hpp"
+#include "supertux/timer.hpp"
+
+class DrawingContext;
+class Surface;
+
+/**
+ * Screen that welcomes the player to a level
+ */
+class LevelIntro : public Screen
+{
+private:
+ static Color header_color;
+ static Color author_color;
+ static Color stat_hdr_color;
+ static Color stat_color;
+
+public:
+ LevelIntro(const Level* level, const Statistics* best_level_statistics);
+ virtual ~LevelIntro();
+
+ void setup();
+ void draw(DrawingContext& context);
+ void update(float elapsed_time);
+
+private:
+ const Level* level; /**< The level of which this is the intro screen */
+ const Statistics* best_level_statistics; /**< Best level statistics of the level of which is the intro screen */
+ std::auto_ptr<Sprite> player_sprite; /**< Sprite representing the player */
+ float player_sprite_py; /**< Position (y axis) for the player sprite */
+ float player_sprite_vy; /**< Velocity (y axis) for the player sprite */
+ Timer player_sprite_jump_timer; /**< When timer fires, the player sprite will "jump" */
+};
+
+#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include <config.h>
+#include <version.h>
+
+#include <SDL_image.h>
+#include <physfs.h>
+#include <iostream>
+
+#ifdef MACOSX
+namespace supertux_apple {
+}
+#endif
+
+#include "addon/addon_manager.hpp"
+#include "audio/sound_manager.hpp"
+#include "binreloc/binreloc.h"
+#include "control/joystickkeyboardcontroller.hpp"
+#include "math/random_generator.hpp"
+#include "physfs/physfs_sdl.hpp"
+#include "scripting/squirrel_util.hpp"
+#include "supertux/gameconfig.hpp"
+#include "supertux/mainloop.hpp"
+#include "supertux/resources.hpp"
+#include "supertux/title.hpp"
+#include "util/file_system.hpp"
+#include "util/gettext.hpp"
+#include "video/drawing_context.hpp"
+#include "worldmap/worldmap.hpp"
+
+namespace { DrawingContext *context_pointer; }
+
+SDL_Surface* g_screen;
+JoystickKeyboardController* g_main_controller = 0;
+TinyGetText::DictionaryManager dictionary_manager;
+
+int SCREEN_WIDTH;
+int SCREEN_HEIGHT;
+
+static void init_config()
+{
+ g_config = new Config();
+ try {
+ g_config->load();
+ } catch(std::exception& e) {
+ log_info << "Couldn't load config file: " << e.what() << ", using default settings" << std::endl;
+ }
+}
+
+static void init_tinygettext()
+{
+ dictionary_manager.add_directory("locale");
+ dictionary_manager.set_charset("UTF-8");
+
+ // Config setting "locale" overrides language detection
+ if (g_config->locale != "") {
+ dictionary_manager.set_language( g_config->locale );
+ }
+}
+
+static void init_physfs(const char* argv0)
+{
+ if(!PHYSFS_init(argv0)) {
+ std::stringstream msg;
+ msg << "Couldn't initialize physfs: " << PHYSFS_getLastError();
+ throw std::runtime_error(msg.str());
+ }
+
+ // allow symbolic links
+ PHYSFS_permitSymbolicLinks(1);
+
+ // Initialize physfs (this is a slightly modified version of
+ // PHYSFS_setSaneConfig
+ const char* application = "supertux2"; //instead of PACKAGE_NAME so we can coexist with MS1
+ const char* userdir = PHYSFS_getUserDir();
+ char* writedir = new char[strlen(userdir) + strlen(application) + 2];
+
+ // Set configuration directory
+ sprintf(writedir, "%s.%s", userdir, application);
+ if(!PHYSFS_setWriteDir(writedir)) {
+ // try to create the directory
+ char* mkdir = new char[strlen(application) + 2];
+ sprintf(mkdir, ".%s", application);
+ if(!PHYSFS_setWriteDir(userdir) || !PHYSFS_mkdir(mkdir)) {
+ std::ostringstream msg;
+ msg << "Failed creating configuration directory '"
+ << writedir << "': " << PHYSFS_getLastError();
+ delete[] writedir;
+ delete[] mkdir;
+ throw std::runtime_error(msg.str());
+ }
+ delete[] mkdir;
+
+ if(!PHYSFS_setWriteDir(writedir)) {
+ std::ostringstream msg;
+ msg << "Failed to use configuration directory '"
+ << writedir << "': " << PHYSFS_getLastError();
+ delete[] writedir;
+ throw std::runtime_error(msg.str());
+ }
+ }
+ PHYSFS_addToSearchPath(writedir, 0);
+ delete[] writedir;
+
+ // when started from source dir...
+ std::string dir = PHYSFS_getBaseDir();
+ dir += "/data";
+ std::string testfname = dir;
+ testfname += "/credits.txt";
+ bool sourcedir = false;
+ FILE* f = fopen(testfname.c_str(), "r");
+ if(f) {
+ fclose(f);
+ if(!PHYSFS_addToSearchPath(dir.c_str(), 1)) {
+ log_warning << "Couldn't add '" << dir << "' to physfs searchpath: " << PHYSFS_getLastError() << std::endl;
+ } else {
+ sourcedir = true;
+ }
+ }
+
+#ifdef MACOSX
+ {
+ using namespace supertux_apple;
+
+ // when started from Application file on Mac OS X...
+ char path[PATH_MAX];
+ CFBundleRef mainBundle = CFBundleGetMainBundle();
+ assert(mainBundle != 0);
+ CFURLRef mainBundleURL = CFBundleCopyBundleURL(mainBundle);
+ assert(mainBundleURL != 0);
+ CFStringRef pathStr = CFURLCopyFileSystemPath(mainBundleURL, kCFURLPOSIXPathStyle);
+ assert(pathStr != 0);
+ CFStringGetCString(pathStr, path, PATH_MAX, kCFStringEncodingUTF8);
+ CFRelease(mainBundleURL);
+ CFRelease(pathStr);
+
+ dir = std::string(path) + "/Contents/Resources/data";
+ testfname = dir + "/credits.txt";
+ sourcedir = false;
+ f = fopen(testfname.c_str(), "r");
+ if(f) {
+ fclose(f);
+ if(!PHYSFS_addToSearchPath(dir.c_str(), 1)) {
+ log_warning << "Couldn't add '" << dir << "' to physfs searchpath: " << PHYSFS_getLastError() << std::endl;
+ } else {
+ sourcedir = true;
+ }
+ }
+ }
+#endif
+
+#ifdef _WIN32
+ PHYSFS_addToSearchPath(".\\data", 1);
+#endif
+
+ if(!sourcedir) {
+#if defined(APPDATADIR) || defined(ENABLE_BINRELOC)
+ std::string datadir;
+#ifdef ENABLE_BINRELOC
+
+ char* dir;
+ br_init (NULL);
+ dir = br_find_data_dir(APPDATADIR);
+ datadir = dir;
+ free(dir);
+
+#else
+ datadir = APPDATADIR;
+#endif
+ if(!PHYSFS_addToSearchPath(datadir.c_str(), 1)) {
+ log_warning << "Couldn't add '" << datadir << "' to physfs searchpath: " << PHYSFS_getLastError() << std::endl;
+ }
+#endif
+ }
+
+ //show search Path
+ char** searchpath = PHYSFS_getSearchPath();
+ for(char** i = searchpath; *i != NULL; i++)
+ log_info << "[" << *i << "] is in the search path" << std::endl;
+ PHYSFS_freeList(searchpath);
+}
+
+static void print_usage(const char* argv0)
+{
+ fprintf(stderr, _("Usage: %s [OPTIONS] [LEVELFILE]\n\n"), argv0);
+ fprintf(stderr,
+ _("Options:\n"
+ " -f, --fullscreen Run in fullscreen mode\n"
+ " -w, --window Run in window mode\n"
+ " -g, --geometry WIDTHxHEIGHT Run SuperTux in given resolution\n"
+ " -a, --aspect WIDTH:HEIGHT Run SuperTux with given aspect ratio\n"
+ " -d, --default Reset video settings to default values\n"
+ " --renderer RENDERER Use sdl, opengl, or auto to render\n"
+ " --disable-sfx Disable sound effects\n"
+ " --disable-music Disable music\n"
+ " -h, --help Show this help message and quit\n"
+ " -v, --version Show SuperTux version and quit\n"
+ " --console Enable ingame scripting console\n"
+ " --noconsole Disable ingame scripting console\n"
+ " --show-fps Display framerate in levels\n"
+ " --no-show-fps Do not display framerate in levels\n"
+ " --record-demo FILE LEVEL Record a demo to FILE\n"
+ " --play-demo FILE LEVEL Play a recorded demo\n"
+ " -s, --debug-scripts Enable script debugger.\n"
+ "%s\n"), "");
+}
+
+/**
+ * Options that should be evaluated prior to any initializations at all go here
+ */
+static bool pre_parse_commandline(int argc, char** argv)
+{
+ for(int i = 1; i < argc; ++i) {
+ std::string arg = argv[i];
+
+ if(arg == "--version" || arg == "-v") {
+ std::cout << PACKAGE_NAME << " " << PACKAGE_VERSION << std::endl;
+ return true;
+ }
+ if(arg == "--help" || arg == "-h") {
+ print_usage(argv[0]);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/**
+ * Options that should be evaluated after config is read go here
+ */
+static bool parse_commandline(int argc, char** argv)
+{
+ for(int i = 1; i < argc; ++i) {
+ std::string arg = argv[i];
+
+ if(arg == "--fullscreen" || arg == "-f") {
+ g_config->use_fullscreen = true;
+ } else if(arg == "--default" || arg == "-d") {
+ g_config->use_fullscreen = false;
+
+ g_config->window_width = 800;
+ g_config->window_height = 600;
+
+ g_config->fullscreen_width = 800;
+ g_config->fullscreen_height = 600;
+
+ g_config->aspect_width = 0; // auto detect
+ g_config->aspect_height = 0;
+
+ } else if(arg == "--window" || arg == "-w") {
+ g_config->use_fullscreen = false;
+ } else if(arg == "--geometry" || arg == "-g") {
+ i += 1;
+ if(i >= argc)
+ {
+ print_usage(argv[0]);
+ throw std::runtime_error("Need to specify a size (WIDTHxHEIGHT) for geometry argument");
+ }
+ else
+ {
+ int width, height;
+ if (sscanf(argv[i], "%dx%d", &width, &height) != 2)
+ {
+ print_usage(argv[0]);
+ throw std::runtime_error("Invalid geometry spec, should be WIDTHxHEIGHT");
+ }
+ else
+ {
+ g_config->window_width = width;
+ g_config->window_height = height;
+
+ g_config->fullscreen_width = width;
+ g_config->fullscreen_height = height;
+ }
+ }
+ } else if(arg == "--aspect" || arg == "-a") {
+ i += 1;
+ if(i >= argc)
+ {
+ print_usage(argv[0]);
+ throw std::runtime_error("Need to specify a ratio (WIDTH:HEIGHT) for aspect ratio");
+ }
+ else
+ {
+ int aspect_width = 0;
+ int aspect_height = 0;
+ if (strcmp(argv[i], "auto") == 0)
+ {
+ aspect_width = 0;
+ aspect_height = 0;
+ }
+ else if (sscanf(argv[i], "%d:%d", &aspect_width, &aspect_height) != 2)
+ {
+ print_usage(argv[0]);
+ throw std::runtime_error("Invalid aspect spec, should be WIDTH:HEIGHT or auto");
+ }
+ else
+ {
+ float aspect_ratio = static_cast<double>(g_config->aspect_width) /
+ static_cast<double>(g_config->aspect_height);
+
+ // use aspect ratio to calculate logical resolution
+ if (aspect_ratio > 1) {
+ g_config->aspect_width = static_cast<int> (600 * aspect_ratio + 0.5);
+ g_config->aspect_height = 600;
+ } else {
+ g_config->aspect_width = 600;
+ g_config->aspect_height = static_cast<int> (600 * 1/aspect_ratio + 0.5);
+ }
+ }
+ }
+ } else if(arg == "--renderer") {
+ i += 1;
+ if(i >= argc)
+ {
+ print_usage(argv[0]);
+ throw std::runtime_error("Need to specify a renderer for renderer argument");
+ }
+ else
+ {
+ g_config->video = get_video_system(argv[i]);
+ }
+ } else if(arg == "--show-fps") {
+ g_config->show_fps = true;
+ } else if(arg == "--no-show-fps") {
+ g_config->show_fps = false;
+ } else if(arg == "--console") {
+ g_config->console_enabled = true;
+ } else if(arg == "--noconsole") {
+ g_config->console_enabled = false;
+ } else if(arg == "--disable-sfx") {
+ g_config->sound_enabled = false;
+ } else if(arg == "--disable-music") {
+ g_config->music_enabled = false;
+ } else if(arg == "--play-demo") {
+ if(i+1 >= argc) {
+ print_usage(argv[0]);
+ throw std::runtime_error("Need to specify a demo filename");
+ }
+ g_config->start_demo = argv[++i];
+ } else if(arg == "--record-demo") {
+ if(i+1 >= argc) {
+ print_usage(argv[0]);
+ throw std::runtime_error("Need to specify a demo filename");
+ }
+ g_config->record_demo = argv[++i];
+ } else if(arg == "--debug-scripts" || arg == "-s") {
+ g_config->enable_script_debugger = true;
+ } else if(arg[0] != '-') {
+ g_config->start_level = arg;
+ } else {
+ log_warning << "Unknown option '" << arg << "'. Use --help to see a list of options" << std::endl;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static void init_sdl()
+{
+ if(SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0) {
+ std::stringstream msg;
+ msg << "Couldn't initialize SDL: " << SDL_GetError();
+ throw std::runtime_error(msg.str());
+ }
+ // just to be sure
+ atexit(SDL_Quit);
+
+ SDL_EnableUNICODE(1);
+
+ // wait 100ms and clear SDL event queue because sometimes we have random
+ // joystick events in the queue on startup...
+ SDL_Delay(100);
+ SDL_Event dummy;
+ while(SDL_PollEvent(&dummy))
+ ;
+}
+
+static void init_rand()
+{
+ g_config->random_seed = systemRandom.srand(g_config->random_seed);
+
+ //const char *how = config->random_seed? ", user fixed.": ", from time().";
+ //log_info << "Using random seed " << config->random_seed << how << std::endl;
+}
+
+void init_video()
+{
+ // FIXME: Add something here
+ SCREEN_WIDTH = 800;
+ SCREEN_HEIGHT = 600;
+
+ context_pointer->init_renderer();
+ g_screen = SDL_GetVideoSurface();
+
+ SDL_WM_SetCaption(PACKAGE_NAME " " PACKAGE_VERSION, 0);
+
+ // set icon
+#ifdef MACOSX
+ const char* icon_fname = "images/engine/icons/supertux-256x256.png";
+#else
+ const char* icon_fname = "images/engine/icons/supertux.xpm";
+#endif
+ SDL_Surface* icon;
+ try {
+ icon = IMG_Load_RW(get_physfs_SDLRWops(icon_fname), true);
+ } catch (const std::runtime_error& err) {
+ icon = 0;
+ log_warning << "Couldn't load icon '" << icon_fname << "': " << err.what() << std::endl;
+ }
+ if(icon != 0) {
+ SDL_WM_SetIcon(icon, 0);
+ SDL_FreeSurface(icon);
+ }
+#ifdef DEBUG
+ else {
+ log_warning << "Couldn't load icon '" << icon_fname << "'" << std::endl;
+ }
+#endif
+
+ SDL_ShowCursor(0);
+
+ log_info << (g_config->use_fullscreen?"fullscreen ":"window ")
+ << " Window: " << g_config->window_width << "x" << g_config->window_height
+ << " Fullscreen: " << g_config->fullscreen_width << "x" << g_config->fullscreen_height
+ << " Area: " << g_config->aspect_width << "x" << g_config->aspect_height << std::endl;
+}
+
+static void init_audio()
+{
+ sound_manager = new SoundManager();
+
+ sound_manager->enable_sound(g_config->sound_enabled);
+ sound_manager->enable_music(g_config->music_enabled);
+}
+
+static void quit_audio()
+{
+ if(sound_manager != NULL) {
+ delete sound_manager;
+ sound_manager = NULL;
+ }
+}
+
+void wait_for_event(float min_delay, float max_delay)
+{
+ assert(min_delay <= max_delay);
+
+ Uint32 min = (Uint32) (min_delay * 1000);
+ Uint32 max = (Uint32) (max_delay * 1000);
+
+ Uint32 ticks = SDL_GetTicks();
+ while(SDL_GetTicks() - ticks < min) {
+ SDL_Delay(10);
+ sound_manager->update();
+ }
+
+ // clear event queue
+ SDL_Event event;
+ while (SDL_PollEvent(&event))
+ {}
+
+ /* Handle events: */
+ bool running = false;
+ ticks = SDL_GetTicks();
+ while(running) {
+ while(SDL_PollEvent(&event)) {
+ switch(event.type) {
+ case SDL_QUIT:
+ g_main_loop->quit();
+ break;
+ case SDL_KEYDOWN:
+ case SDL_JOYBUTTONDOWN:
+ case SDL_MOUSEBUTTONDOWN:
+ running = false;
+ }
+ }
+ if(SDL_GetTicks() - ticks >= (max - min))
+ running = false;
+ sound_manager->update();
+ SDL_Delay(10);
+ }
+}
+
+#ifdef DEBUG
+static Uint32 last_timelog_ticks = 0;
+static const char* last_timelog_component = 0;
+
+static inline void timelog(const char* component)
+{
+ Uint32 current_ticks = SDL_GetTicks();
+
+ if(last_timelog_component != 0) {
+ log_info << "Component '" << last_timelog_component << "' finished after " << (current_ticks - last_timelog_ticks) / 1000.0 << " seconds" << std::endl;
+ }
+
+ last_timelog_ticks = current_ticks;
+ last_timelog_component = component;
+}
+#else
+static inline void timelog(const char* )
+{
+}
+#endif
+
+int supertux_main(int argc, char** argv)
+{
+ int result = 0;
+
+ try {
+
+ if(pre_parse_commandline(argc, argv))
+ return 0;
+
+ Console::instance = new Console();
+ init_physfs(argv[0]);
+ init_sdl();
+
+ timelog("controller");
+ g_main_controller = new JoystickKeyboardController();
+
+ timelog("config");
+ init_config();
+
+ timelog("addons");
+ AddonManager::get_instance().load_addons();
+
+ timelog("tinygettext");
+ init_tinygettext();
+
+ timelog("commandline");
+ if(parse_commandline(argc, argv))
+ return 0;
+
+ timelog("audio");
+ init_audio();
+
+ timelog("video");
+ DrawingContext context;
+ context_pointer = &context;
+ init_video();
+
+ Console::instance->init_graphics();
+
+ timelog("scripting");
+ Scripting::init_squirrel(g_config->enable_script_debugger);
+
+ timelog("resources");
+ load_shared();
+
+ timelog(0);
+
+ g_main_loop = new MainLoop();
+ if(g_config->start_level != "") {
+ // we have a normal path specified at commandline, not a physfs path.
+ // So we simply mount that path here...
+ std::string dir = FileSystem::dirname(g_config->start_level);
+ log_debug << "Adding dir: " << dir << std::endl;
+ PHYSFS_addToSearchPath(dir.c_str(), true);
+
+ if(g_config->start_level.size() > 4 &&
+ g_config->start_level.compare(g_config->start_level.size() - 5, 5, ".stwm") == 0) {
+ init_rand();
+ g_main_loop->push_screen(new WorldMapNS::WorldMap(
+ FileSystem::basename(g_config->start_level)));
+ } else {
+ init_rand();//If level uses random eg. for
+ // rain particles before we do this:
+ std::auto_ptr<GameSession> session (
+ new GameSession(FileSystem::basename(g_config->start_level)));
+
+ g_config->random_seed =session->get_demo_random_seed(g_config->start_demo);
+ init_rand();//initialise generator with seed from session
+
+ if(g_config->start_demo != "")
+ session->play_demo(g_config->start_demo);
+
+ if(g_config->record_demo != "")
+ session->record_demo(g_config->record_demo);
+ g_main_loop->push_screen(session.release());
+ }
+ } else {
+ init_rand();
+ g_main_loop->push_screen(new TitleScreen());
+ }
+
+ //init_rand(); PAK: this call might subsume the above 3, but I'm chicken!
+ g_main_loop->run(context);
+ } catch(std::exception& e) {
+ log_fatal << "Unexpected exception: " << e.what() << std::endl;
+ result = 1;
+ } catch(...) {
+ log_fatal << "Unexpected exception" << std::endl;
+ result = 1;
+ }
+
+ delete g_main_loop;
+ g_main_loop = NULL;
+
+ unload_shared();
+ quit_audio();
+
+ if(g_config)
+ g_config->save();
+ delete g_config;
+ g_config = NULL;
+ delete g_main_controller;
+ g_main_controller = NULL;
+ delete Console::instance;
+ Console::instance = NULL;
+ Scripting::exit_squirrel();
+ delete texture_manager;
+ texture_manager = NULL;
+ SDL_Quit();
+ PHYSFS_deinit();
+
+ return result;
+}
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_SUPERTUX_MAIN_HPP
+#define HEADER_SUPERTUX_SUPERTUX_MAIN_HPP
+
+void init_video();
+void wait_for_event(float min_delay, float max_delay);
+
+/** The width of the display (this is a logical value, not the
+ physical value, since aspect_ration and projection_area might
+ shrink or scale things) */
+extern int SCREEN_WIDTH;
+
+/** The width of the display (this is a logical value, not the
+ physical value, since aspect_ration and projection_area might
+ shrink or scale things) */
+extern int SCREEN_HEIGHT;
+
+// global variables
+class JoystickKeyboardController;
+extern JoystickKeyboardController* g_main_controller;
+
+int supertux_main(int argc, char** argv);
+
+#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include "supertux/mainloop.hpp"
+
+#include "audio/sound_manager.hpp"
+#include "control/joystickkeyboardcontroller.hpp"
+#include "gui/menu.hpp"
+#include "scripting/squirrel_util.hpp"
+#include "scripting/time_scheduler.hpp"
+#include "supertux/constants.hpp"
+#include "supertux/console.hpp"
+#include "supertux/gameconfig.hpp"
+#include "supertux/main.hpp"
+#include "supertux/player_status.hpp"
+#include "supertux/resources.hpp"
+#include "supertux/screen_fade.hpp"
+#include "supertux/screen.hpp"
+#include "supertux/timer.hpp"
+#include "video/drawing_context.hpp"
+#include "video/renderer.hpp"
+
+/** ticks (as returned from SDL_GetTicks) per frame */
+static const Uint32 TICKS_PER_FRAME = (Uint32) (1000.0 / LOGICAL_FPS);
+/** don't skip more than every 2nd frame */
+static const int MAX_FRAME_SKIP = 2;
+
+float g_game_speed = 1.0f;
+
+MainLoop* g_main_loop = NULL;
+
+MainLoop::MainLoop() :
+ speed(1.0),
+ nextpop(false),
+ nextpush(false),
+ fps(0),
+ screenshot_requested(false)
+{
+ using namespace Scripting;
+ TimeScheduler::instance = new TimeScheduler();
+}
+
+MainLoop::~MainLoop()
+{
+ using namespace Scripting;
+ delete TimeScheduler::instance;
+ TimeScheduler::instance = NULL;
+
+ for(std::vector<Screen*>::iterator i = screen_stack.begin();
+ i != screen_stack.end(); ++i) {
+ delete *i;
+ }
+}
+
+void
+MainLoop::push_screen(Screen* screen, ScreenFade* screen_fade)
+{
+ this->next_screen.reset(screen);
+ this->screen_fade.reset(screen_fade);
+ nextpush = !nextpop;
+ nextpop = false;
+ speed = 1.0f;
+}
+
+void
+MainLoop::exit_screen(ScreenFade* screen_fade)
+{
+ next_screen.reset(NULL);
+ this->screen_fade.reset(screen_fade);
+ nextpop = true;
+ nextpush = false;
+}
+
+void
+MainLoop::set_screen_fade(ScreenFade* screen_fade)
+{
+ this->screen_fade.reset(screen_fade);
+}
+
+void
+MainLoop::quit(ScreenFade* screen_fade)
+{
+ for(std::vector<Screen*>::iterator i = screen_stack.begin();
+ i != screen_stack.end(); ++i)
+ delete *i;
+ screen_stack.clear();
+
+ exit_screen(screen_fade);
+}
+
+void
+MainLoop::set_speed(float speed)
+{
+ this->speed = speed;
+}
+
+float
+MainLoop::get_speed() const
+{
+ return speed;
+}
+
+bool
+MainLoop::has_no_pending_fadeout() const
+{
+ return screen_fade.get() == NULL || screen_fade->done();
+}
+
+void
+MainLoop::draw_fps(DrawingContext& context, float fps_fps)
+{
+ char str[60];
+ snprintf(str, sizeof(str), "%3.1f", fps_fps);
+ const char* fpstext = "FPS";
+ context.draw_text(small_font, fpstext, Vector(SCREEN_WIDTH - small_font->get_text_width(fpstext) - small_font->get_text_width(" 99999") - BORDER_X, BORDER_Y + 20), ALIGN_LEFT, LAYER_HUD);
+ context.draw_text(small_font, str, Vector(SCREEN_WIDTH - BORDER_X, BORDER_Y + 20), ALIGN_RIGHT, LAYER_HUD);
+}
+
+void
+MainLoop::draw(DrawingContext& context)
+{
+ static Uint32 fps_ticks = SDL_GetTicks();
+ static int frame_count = 0;
+
+ current_screen->draw(context);
+ if(Menu::current() != NULL)
+ Menu::current()->draw(context);
+ if(screen_fade.get() != NULL)
+ screen_fade->draw(context);
+ Console::instance->draw(context);
+
+ if(g_config->show_fps)
+ draw_fps(context, fps);
+
+ // if a screenshot was requested, pass request on to drawing_context
+ if (screenshot_requested) {
+ context.take_screenshot();
+ screenshot_requested = false;
+ }
+ context.do_drawing();
+
+ /* Calculate frames per second */
+ if(g_config->show_fps)
+ {
+ ++frame_count;
+
+ if(SDL_GetTicks() - fps_ticks >= 500)
+ {
+ fps = (float) frame_count / .5;
+ frame_count = 0;
+ fps_ticks = SDL_GetTicks();
+ }
+ }
+}
+
+void
+MainLoop::update_gamelogic(float elapsed_time)
+{
+ Scripting::update_debugger();
+ Scripting::TimeScheduler::instance->update(game_time);
+ current_screen->update(elapsed_time);
+ if (Menu::current() != NULL)
+ Menu::current()->update();
+ if(screen_fade.get() != NULL)
+ screen_fade->update(elapsed_time);
+ Console::instance->update(elapsed_time);
+}
+
+void
+MainLoop::process_events()
+{
+ g_main_controller->update();
+ Uint8* keystate = SDL_GetKeyState(NULL);
+ SDL_Event event;
+ while(SDL_PollEvent(&event))
+ {
+ g_main_controller->process_event(event);
+
+ if(Menu::current() != NULL)
+ Menu::current()->event(event);
+
+ switch(event.type)
+ {
+ case SDL_QUIT:
+ quit();
+ break;
+
+ case SDL_VIDEORESIZE:
+ Renderer::instance()->resize(event.resize.w, event.resize.h);
+ Menu::recalc_pos();
+ break;
+
+ case SDL_KEYDOWN:
+ if (event.key.keysym.sym == SDLK_F10)
+ {
+ g_config->show_fps = !g_config->show_fps;
+ }
+ if (event.key.keysym.sym == SDLK_F11)
+ {
+ g_config->use_fullscreen = !g_config->use_fullscreen;
+ init_video();
+ Menu::recalc_pos();
+ }
+ else if (event.key.keysym.sym == SDLK_PRINT ||
+ event.key.keysym.sym == SDLK_F12)
+ {
+ take_screenshot();
+ }
+ else if (event.key.keysym.sym == SDLK_F1 &&
+ (keystate[SDLK_LCTRL] || keystate[SDLK_RCTRL]) &&
+ keystate[SDLK_c])
+ {
+ Console::instance->toggle();
+ g_config->console_enabled = true;
+ g_config->save();
+ }
+ break;
+ }
+ }
+}
+
+void
+MainLoop::handle_screen_switch()
+{
+ while( (next_screen.get() != NULL || nextpop) &&
+ has_no_pending_fadeout()) {
+ if(current_screen.get() != NULL) {
+ current_screen->leave();
+ }
+
+ if(nextpop) {
+ if(screen_stack.empty()) {
+ running = false;
+ break;
+ }
+ next_screen.reset(screen_stack.back());
+ screen_stack.pop_back();
+ }
+ if(nextpush && current_screen.get() != NULL) {
+ screen_stack.push_back(current_screen.release());
+ }
+
+ nextpush = false;
+ nextpop = false;
+ speed = 1.0;
+ Screen* next_screen_ptr = next_screen.release();
+ next_screen.reset(0);
+ if(next_screen_ptr)
+ next_screen_ptr->setup();
+ current_screen.reset(next_screen_ptr);
+ screen_fade.reset(NULL);
+
+ waiting_threads.wakeup();
+ }
+}
+
+void
+MainLoop::run(DrawingContext &context)
+{
+ Uint32 last_ticks = 0;
+ Uint32 elapsed_ticks = 0;
+
+ running = true;
+ while(running) {
+
+ handle_screen_switch();
+ if(!running || current_screen.get() == NULL)
+ break;
+
+ Uint32 ticks = SDL_GetTicks();
+ elapsed_ticks += ticks - last_ticks;
+ last_ticks = ticks;
+
+ Uint32 ticks_per_frame = (Uint32) (TICKS_PER_FRAME * g_game_speed);
+
+ if (elapsed_ticks > ticks_per_frame*4) {
+ // when the game loads up or levels are switched the
+ // elapsed_ticks grows extremely large, so we just ignore those
+ // large time jumps
+ elapsed_ticks = 0;
+ }
+
+ if(elapsed_ticks < ticks_per_frame)
+ {
+ Uint32 delay_ticks = ticks_per_frame - elapsed_ticks;
+ SDL_Delay(delay_ticks);
+ last_ticks += delay_ticks;
+ elapsed_ticks += delay_ticks;
+ }
+
+ int frames = 0;
+
+ while(elapsed_ticks >= ticks_per_frame && frames < MAX_FRAME_SKIP)
+ {
+ elapsed_ticks -= ticks_per_frame;
+ float timestep = 1.0 / LOGICAL_FPS;
+ real_time += timestep;
+ timestep *= speed;
+ game_time += timestep;
+
+ process_events();
+ update_gamelogic(timestep);
+ frames += 1;
+ }
+
+ draw(context);
+
+ sound_manager->update();
+ }
+}
+
+void
+MainLoop::take_screenshot()
+{
+ screenshot_requested = true;
+}
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_SUPERTUX_MAINLOOP_HPP
+#define HEADER_SUPERTUX_SUPERTUX_MAINLOOP_HPP
+
+#include <memory>
+
+#include "scripting/thread_queue.hpp"
+
+class Screen;
+class Console;
+class ScreenFade;
+class DrawingContext;
+
+/**
+ * Manages, updates and draws all Screens, Controllers, Menus and the Console.
+ */
+class MainLoop
+{
+public:
+ MainLoop();
+ ~MainLoop();
+
+ void run(DrawingContext &context);
+ void exit_screen(ScreenFade* fade = NULL);
+ void quit(ScreenFade* fade = NULL);
+ void set_speed(float speed);
+ float get_speed() const;
+ bool has_no_pending_fadeout() const;
+
+ /**
+ * requests that a screenshot be taken after the next frame has been rendered
+ */
+ void take_screenshot();
+
+ // push new screen on screen_stack
+ void push_screen(Screen* screen, ScreenFade* fade = NULL);
+ void set_screen_fade(ScreenFade* fade);
+
+ /// threads that wait for a screenswitch
+ Scripting::ThreadQueue waiting_threads;
+
+private:
+ void draw_fps(DrawingContext& context, float fps);
+ void draw(DrawingContext& context);
+ void update_gamelogic(float elapsed_time);
+ void process_events();
+ void handle_screen_switch();
+
+ bool running;
+ float speed;
+ bool nextpop;
+ bool nextpush;
+ /// measured fps
+ float fps;
+ std::auto_ptr<Screen> next_screen;
+ std::auto_ptr<Screen> current_screen;
+ std::auto_ptr<Console> console;
+ std::auto_ptr<ScreenFade> screen_fade;
+ std::vector<Screen*> screen_stack;
+ bool screenshot_requested; /**< true if a screenshot should be taken after the next frame has been rendered */
+};
+
+extern MainLoop* g_main_loop;
+
+#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include "supertux/moving_object.hpp"
+
+MovingObject::MovingObject()
+{
+ group = COLGROUP_MOVING;
+}
+
+MovingObject::~MovingObject()
+{
+}
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_SUPERTUX_MOVING_OBJECT_HPP
+#define HEADER_SUPERTUX_SUPERTUX_MOVING_OBJECT_HPP
+
+#include <stdint.h>
+
+#include "math/rect.hpp"
+#include "supertux/collision_hit.hpp"
+#include "supertux/game_object.hpp"
+
+class Sector;
+class CollisionGrid;
+
+enum CollisionGroup {
+ /** Objects in DISABLED group are not tested for collisions */
+ COLGROUP_DISABLED = 0,
+
+ /** "default" is moving object. MovingObjects get tested against all
+ other objects and against other movingobjects */
+ COLGROUP_MOVING,
+
+ /** a Moving object, that is not tested against other MovingObjects
+ (or other MovingOnlyStatic objects), but is tested against all
+ other objects. */
+ COLGROUP_MOVING_ONLY_STATIC,
+
+ /** TODO write docu :-/ */
+ COLGROUP_MOVING_STATIC,
+
+ /**
+ * Doesn't move and isn't explicitly checked for collisions with
+ * other objects (but other objects might check with this) The
+ * difference to COLGROUP_TOUCHABLE is that we can do multiple
+ * collision response tests in a row which is needed for static object
+ * that tux walks on. The results for collisions with STATIC objects
+ * are also sorted by time (so that the first hit gets handled first).
+ *
+ * Use this for static obstacles
+ */
+ COLGROUP_STATIC,
+
+ /** Isn't explicitly checked for collisions with other objects. But
+ other objects might check with this object. Difference to
+ COLGROUP_STATIC is that collisions with this object are only
+ tested once and collision response is typically not handled
+
+ Use this for touchable things like spikes/areas or collectibles
+ like coins */
+ COLGROUP_TOUCHABLE,
+
+ /** Should be used for tilemaps */
+ COLGROUP_TILEMAP
+};
+
+/** Base class for all dynamic/moving game objects. This class
+ contains things for handling the bounding boxes and collision
+ feedback. */
+class MovingObject : public GameObject
+{
+public:
+ MovingObject();
+ virtual ~MovingObject();
+
+ /** this function is called when the object collided with something solid */
+ virtual void collision_solid(const CollisionHit& hit)
+ {
+ (void) hit;
+ }
+
+ /** when 2 objects collided, we will first call the
+ pre_collision_check functions of both objects that can decide on
+ how to react to the collision. */
+ virtual bool collides(GameObject& other, const CollisionHit& hit)
+ {
+ (void) other;
+ (void) hit;
+ return true;
+ }
+
+ /** this function is called when the object collided with any other object */
+ virtual HitResponse collision(GameObject& other, const CollisionHit& hit) = 0;
+
+ /** called when tiles with special attributes have been touched */
+ virtual void collision_tile(uint32_t tile_attributes)
+ {
+ (void) tile_attributes;
+ }
+
+ const Vector& get_pos() const
+ {
+ return bbox.p1;
+ }
+
+ /** returns the bounding box of the Object */
+ const Rect& get_bbox() const
+ {
+ return bbox;
+ }
+
+ const Vector& get_movement() const
+ {
+ return movement;
+ }
+
+ /** places the moving object at a specific position. Be careful when
+ using this function. There are no collision detection checks
+ performed here so bad things could happen. */
+ virtual void set_pos(const Vector& pos)
+ {
+ dest.move(pos-get_pos());
+ bbox.set_pos(pos);
+ }
+
+ /** sets the moving object's bbox to a specific width. Be careful
+ when using this function. There are no collision detection
+ checks performed here so bad things could happen. */
+ virtual void set_width(float w)
+ {
+ dest.set_width(w);
+ bbox.set_width(w);
+ }
+
+ /** sets the moving object's bbox to a specific size. Be careful
+ when using this function. There are no collision detection
+ checks performed here so bad things could happen. */
+ virtual void set_size(float w, float h)
+ {
+ dest.set_size(w, h);
+ bbox.set_size(w, h);
+ }
+
+ CollisionGroup get_group() const
+ {
+ return group;
+ }
+
+protected:
+ friend class Sector;
+ friend class CollisionGrid;
+ friend class Platform;
+
+ void set_group(CollisionGroup group)
+ {
+ this->group = group;
+ }
+
+ /** The bounding box of the object (as used for collision detection,
+ this isn't necessarily the bounding box for graphics) */
+ Rect bbox;
+
+ /** The movement that will happen till next frame */
+ Vector movement;
+
+ /** The collision group */
+ CollisionGroup group;
+
+private:
+ /** this is only here for internal collision detection use (don't touch this
+ from outside collision detection code)
+
+ This field holds the currently anticipated destination of the object
+ during collision detection */
+ Rect dest;
+};
+
+#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2004 Ricardo Cruz <rick2@aeiou.pt>
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include <sstream>
+#include <stdexcept>
+
+#include "lisp/lisp.hpp"
+#include "lisp/parser.hpp"
+#include "math/vector.hpp"
+#include "supertux/object_factory.hpp"
+
+GameObject* create_object(const std::string& name, const Reader& reader)
+{
+ Factory::Factories::iterator i = Factory::get_factories().find(name);
+ if(i == Factory::get_factories().end()) {
+ std::stringstream msg;
+ msg << "No factory for object '" << name << "' found.";
+ throw std::runtime_error(msg.str());
+ }
+
+ return i->second->create_object(reader);
+}
+
+GameObject* create_object(const std::string& name, const Vector& pos, const Direction dir)
+{
+ std::stringstream lisptext;
+ lisptext << "((x " << pos.x << ")"
+ << " (y " << pos.y << ")";
+ if(dir != AUTO)
+ lisptext << " (direction " << dir << "))";
+
+ lisp::Parser parser;
+ const lisp::Lisp* lisp = parser.parse(lisptext, "create_object");
+ GameObject* object = create_object(name, *(lisp->get_car()));
+
+ return object;
+}
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2004 Ricardo Cruz <rick2@aeiou.pt>
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_SUPERTUX_OBJECT_FACTORY_HPP
+#define HEADER_SUPERTUX_SUPERTUX_OBJECT_FACTORY_HPP
+
+#include <map>
+
+#include "supertux/direction.hpp"
+#include "util/reader_fwd.hpp"
+
+class Vector;
+class GameObject;
+
+class Factory
+{
+public:
+ virtual ~Factory()
+ { }
+
+ /** Creates a new gameobject from a lisp node.
+ * Remember to delete the objects later
+ */
+ virtual GameObject* create_object(const Reader& reader) = 0;
+
+ typedef std::map<std::string, Factory*> Factories;
+ static Factories &get_factories()
+ {
+ static Factories object_factories;
+ return object_factories;
+ }
+};
+
+GameObject* create_object(const std::string& name, const Reader& reader);
+GameObject* create_object(const std::string& name, const Vector& pos, const Direction dir = AUTO);
+
+/** comment from Matze:
+ * Yes I know macros are evil, but in this specific case they save
+ * A LOT of typing and evil code duplication.
+ * I'll happily accept alternatives if someone can present me one that does
+ * not involve typing 4 or more lines for each object class
+ */
+#define IMPLEMENT_FACTORY(CLASS, NAME) \
+ class INTERN_##CLASS##Factory : public Factory \
+ { \
+ public: \
+ INTERN_##CLASS##Factory() \
+ { \
+ get_factories()[NAME] = this; \
+ } \
+ \
+ ~INTERN_##CLASS##Factory() \
+ { \
+ get_factories().erase(NAME); \
+ } \
+ \
+ virtual GameObject* create_object(const Reader& reader) \
+ { \
+ return new CLASS(reader); \
+ } \
+ }; \
+ static INTERN_##CLASS##Factory factory_##CLASS
+
+#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_SUPERTUX_OBJECT_REMOVE_LISTENER_HPP
+#define HEADER_SUPERTUX_SUPERTUX_OBJECT_REMOVE_LISTENER_HPP
+
+class GameObject;
+
+class ObjectRemoveListener
+{
+public:
+ virtual ~ObjectRemoveListener()
+ {}
+
+ virtual void object_removed(GameObject* object) = 0;
+};
+
+#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2004 Tobas Glaesser <tobi.web@gmx.de>
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include "audio/sound_manager.hpp"
+#include "control/joystickkeyboardcontroller.hpp"
+#include "gui/menu.hpp"
+#include "supertux/gameconfig.hpp"
+#include "supertux/main.hpp"
+#include "supertux/profile_menu.hpp"
+#include "util/gettext.hpp"
+#include "video/renderer.hpp"
+
+Menu* options_menu = 0;
+
+enum OptionsMenuIDs {
+ MNID_FULLSCREEN,
+ MNID_FULLSCREEN_RESOLUTION,
+ MNID_MAGNIFICATION,
+ MNID_ASPECTRATIO,
+ MNID_PROFILES,
+ MNID_SOUND,
+ MNID_MUSIC
+};
+
+class LanguageMenu : public Menu
+{
+public:
+ LanguageMenu() {
+ add_label(_("Language"));
+ add_hl();
+ add_entry(0, std::string("<")+_("auto-detect")+">");
+ add_entry(1, "English");
+
+ int mnid = 10;
+ std::set<std::string> languages = dictionary_manager.get_languages();
+ for (std::set<std::string>::iterator i = languages.begin(); i != languages.end(); i++) {
+ std::string locale_name = *i;
+ TinyGetText::LanguageDef ldef = TinyGetText::get_language_def(locale_name);
+ std::string locale_fullname = locale_name;
+ if (std::string(ldef.code) == locale_name) {
+ locale_fullname = ldef.name;
+ }
+ add_entry(mnid++, locale_fullname);
+ }
+
+ add_hl();
+ add_back(_("Back"));
+ }
+
+ virtual void menu_action(MenuItem* item) {
+ if (item->id == 0) {
+ g_config->locale = "";
+ dictionary_manager.set_language(g_config->locale);
+ g_config->save();
+ Menu::pop_current();
+ }
+ else if (item->id == 1) {
+ g_config->locale = "en";
+ dictionary_manager.set_language(g_config->locale);
+ g_config->save();
+ Menu::pop_current();
+ }
+ int mnid = 10;
+ std::set<std::string> languages = dictionary_manager.get_languages();
+ for (std::set<std::string>::iterator i = languages.begin(); i != languages.end(); i++) {
+ std::string locale_name = *i;
+ if (item->id == mnid++) {
+ g_config->locale = locale_name;
+ dictionary_manager.set_language(g_config->locale);
+ g_config->save();
+ Menu::pop_current();
+ }
+ }
+ }
+};
+
+class OptionsMenu : public Menu
+{
+public:
+ OptionsMenu();
+ virtual ~OptionsMenu();
+
+ virtual void menu_action(MenuItem* item);
+
+protected:
+ std::auto_ptr<LanguageMenu> language_menu;
+
+};
+
+OptionsMenu::OptionsMenu()
+{
+ language_menu.reset(new LanguageMenu());
+
+ add_label(_("Options"));
+ add_hl();
+
+ // Language change should only be possible in the main menu, since elsewhere it might not always work fully
+ // FIXME: Implement me: if (get_parent() == main_menu)
+ add_submenu(_("Select Language"), language_menu.get())
+ ->set_help(_("Select a different language to display text in"));
+
+ add_submenu(_("Select Profile"), get_profile_menu())
+ ->set_help(_("Select a profile to play with"));
+
+ add_toggle(MNID_PROFILES, _("Profile on Startup"), g_config->sound_enabled)
+ ->set_help(_("Select your profile immediately after start-up"));
+
+ add_toggle(MNID_FULLSCREEN,_("Fullscreen"), g_config->use_fullscreen)
+ ->set_help(_("Fill the entire screen"));
+
+ MenuItem* fullscreen_res = add_string_select(MNID_FULLSCREEN_RESOLUTION, _("Resolution"));
+ fullscreen_res->set_help(_("Determine the resolution used in fullscreen mode (you must toggle fullscreen to complete the change)"));
+
+ MenuItem* magnification = add_string_select(MNID_MAGNIFICATION, _("Magnification"));
+ magnification->set_help(_("Change the magnification of the game area"));
+
+ // These values go from screen:640/projection:1600 to
+ // screen:1600/projection:640 (i.e. 640, 800, 1024, 1280, 1600)
+ magnification->list.push_back("auto");
+ magnification->list.push_back("40%");
+ magnification->list.push_back("50%");
+ magnification->list.push_back("62.5%");
+ magnification->list.push_back("80%");
+ magnification->list.push_back("100%");
+ magnification->list.push_back("125%");
+ magnification->list.push_back("160%");
+ magnification->list.push_back("200%");
+ magnification->list.push_back("250%");
+
+ SDL_Rect** modes = SDL_ListModes(NULL, SDL_FULLSCREEN|SDL_OPENGL);
+
+ if (modes == (SDL_Rect **)0)
+ { // No resolutions at all available, bad
+
+ }
+ else if(modes == (SDL_Rect **)-1)
+ { // All resolutions should work, so we fall back to hardcoded defaults
+ fullscreen_res->list.push_back("640x480");
+ fullscreen_res->list.push_back("800x600");
+ fullscreen_res->list.push_back("1024x768");
+ fullscreen_res->list.push_back("1152x864");
+ fullscreen_res->list.push_back("1280x960");
+ fullscreen_res->list.push_back("1280x1024");
+ fullscreen_res->list.push_back("1440x900");
+ fullscreen_res->list.push_back("1680x1050");
+ fullscreen_res->list.push_back("1600x1200");
+ fullscreen_res->list.push_back("1920x1080");
+ fullscreen_res->list.push_back("1920x1200");
+ }
+ else
+ {
+ for(int i = 0; modes[i]; ++i)
+ {
+ std::ostringstream out;
+ out << modes[i]->w << "x" << modes[i]->h;
+ fullscreen_res->list.push_back(out.str());
+ }
+ }
+
+ MenuItem* aspect = add_string_select(MNID_ASPECTRATIO, _("Aspect Ratio"));
+ aspect->set_help(_("Adjust the aspect ratio"));
+
+ aspect->list.push_back("auto");
+ aspect->list.push_back("5:4");
+ aspect->list.push_back("4:3");
+ aspect->list.push_back("16:10");
+ aspect->list.push_back("16:9");
+ aspect->list.push_back("1368:768");
+
+ if (g_config->aspect_width != 0 && g_config->aspect_height != 0)
+ {
+ std::ostringstream out;
+ out << g_config->aspect_width << ":" << g_config->aspect_height;
+ std::string aspect_ratio = out.str();
+ for(std::vector<std::string>::iterator i = aspect->list.begin(); i != aspect->list.end(); ++i)
+ {
+ if(*i == aspect_ratio)
+ {
+ aspect_ratio.clear();
+ break;
+ }
+ }
+
+ if (!aspect_ratio.empty())
+ {
+ aspect->selected = aspect->list.size();
+ aspect->list.push_back(aspect_ratio);
+ }
+ }
+
+ if (sound_manager->is_audio_enabled()) {
+ add_toggle(MNID_SOUND, _("Sound"), g_config->sound_enabled)
+ ->set_help(_("Disable all sound effects"));
+ add_toggle(MNID_MUSIC, _("Music"), g_config->music_enabled)
+ ->set_help(_("Disable all music"));
+ } else {
+ add_inactive(MNID_SOUND, _("Sound (disabled)"));
+ add_inactive(MNID_MUSIC, _("Music (disabled)"));
+ }
+
+ add_submenu(_("Setup Keyboard"), g_main_controller->get_key_options_menu())
+ ->set_help(_("Configure key-action mappings"));
+
+ add_submenu(_("Setup Joystick") ,g_main_controller->get_joystick_options_menu())
+ ->set_help(_("Configure joystick control-action mappings"));
+ add_hl();
+ add_back(_("Back"));
+}
+
+OptionsMenu::~OptionsMenu()
+{
+}
+
+void
+OptionsMenu::menu_action(MenuItem* item)
+{
+ switch (item->id) {
+ case MNID_ASPECTRATIO:
+ {
+ if (item->list[item->selected] == "auto")
+ {
+ g_config->aspect_width = 0; // Magic values
+ g_config->aspect_height = 0;
+ Renderer::instance()->apply_config();
+ Menu::recalc_pos();
+ }
+ else if(sscanf(item->list[item->selected].c_str(), "%d:%d", &g_config->aspect_width, &g_config->aspect_height) == 2)
+ {
+ Renderer::instance()->apply_config();
+ Menu::recalc_pos();
+ }
+ else
+ {
+ assert(!"This must not be reached");
+ }
+ }
+ break;
+
+ case MNID_MAGNIFICATION:
+ if (item->list[item->selected] == "auto")
+ {
+ g_config->magnification = 0.0f; // Magic value
+ }
+ else if(sscanf(item->list[item->selected].c_str(), "%f", &g_config->magnification) == 1)
+ {
+ g_config->magnification /= 100.0f;
+ }
+ Renderer::instance()->apply_config();
+ Menu::recalc_pos();
+ break;
+
+ case MNID_FULLSCREEN_RESOLUTION:
+ if(sscanf(item->list[item->selected].c_str(), "%dx%d", &g_config->fullscreen_width, &g_config->fullscreen_height) == 2)
+ {
+ // do nothing, changes are only applied when toggling fullscreen mode
+ }
+ break;
+
+ case MNID_FULLSCREEN:
+ if(g_config->use_fullscreen != options_menu->is_toggled(MNID_FULLSCREEN)) {
+ g_config->use_fullscreen = !g_config->use_fullscreen;
+ init_video(); // FIXME: Should call apply_config instead
+ Menu::recalc_pos();
+ g_config->save();
+ }
+ break;
+
+ case MNID_SOUND:
+ if(g_config->sound_enabled != options_menu->is_toggled(MNID_SOUND)) {
+ g_config->sound_enabled = !g_config->sound_enabled;
+ sound_manager->enable_sound(g_config->sound_enabled);
+ g_config->save();
+ }
+ break;
+
+ case MNID_MUSIC:
+ if(g_config->music_enabled != options_menu->is_toggled(MNID_MUSIC)) {
+ g_config->music_enabled = !g_config->music_enabled;
+ sound_manager->enable_music(g_config->music_enabled);
+ g_config->save();
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+Menu* get_options_menu()
+{
+ //static OptionsMenu menu;
+ options_menu = new OptionsMenu();
+ return options_menu;
+}
+
+void free_options_menu()
+{
+ delete options_menu;
+ options_menu = 0;
+}
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2004 Tobas Glaesser <tobi.web@gmx.de>
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_SUPERTUX_OPTIONS_MENU_HPP
+#define HEADER_SUPERTUX_SUPERTUX_OPTIONS_MENU_HPP
+
+class Menu;
+Menu* get_options_menu();
+void free_options_menu();
+
+#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include "supertux/physic.hpp"
+
+#include "supertux/sector.hpp"
+
+Physic::Physic() :
+ ax(0), ay(0),
+ vx(0), vy(0),
+ gravity_enabled_flag(true),
+ gravity_modifier(1.0f)
+{
+}
+
+Physic::~Physic()
+{
+}
+
+void
+Physic::reset()
+{
+ ax = ay = vx = vy = 0;
+ gravity_enabled_flag = true;
+}
+
+void
+Physic::set_velocity_x(float nvx)
+{
+ vx = nvx;
+}
+
+void
+Physic::set_velocity_y(float nvy)
+{
+ vy = nvy;
+}
+
+void
+Physic::set_velocity(float nvx, float nvy)
+{
+ vx = nvx;
+ vy = nvy;
+}
+
+void
+Physic::set_velocity(const Vector& vector)
+{
+ vx = vector.x;
+ vy = vector.y;
+}
+
+void Physic::inverse_velocity_x()
+{
+ vx = -vx;
+}
+
+void Physic::inverse_velocity_y()
+{
+ vy = -vy;
+}
+
+float
+Physic::get_velocity_x() const
+{
+ return vx;
+}
+
+float
+Physic::get_velocity_y() const
+{
+ return vy;
+}
+
+Vector
+Physic::get_velocity() const
+{
+ return Vector(vx, vy);
+}
+
+void
+Physic::set_acceleration_x(float nax)
+{
+ ax = nax;
+}
+
+void
+Physic::set_acceleration_y(float nay)
+{
+ ay = nay;
+}
+
+void
+Physic::set_acceleration(float nax, float nay)
+{
+ ax = nax;
+ ay = nay;
+}
+
+float
+Physic::get_acceleration_x() const
+{
+ return ax;
+}
+
+float
+Physic::get_acceleration_y() const
+{
+ return ay;
+}
+
+Vector
+Physic::get_acceleration() const
+{
+ return Vector(ax, ay);
+}
+
+void
+Physic::enable_gravity(bool enable_gravity)
+{
+ gravity_enabled_flag = enable_gravity;
+}
+
+bool
+Physic::gravity_enabled() const
+{
+ return gravity_enabled_flag;
+}
+
+void
+Physic::set_gravity_modifier(float gravity_modifier)
+{
+ this->gravity_modifier = gravity_modifier;
+}
+
+Vector
+Physic::get_movement(float elapsed_time)
+{
+ float grav = gravity_enabled_flag ? (Sector::current()->get_gravity() * gravity_modifier * 100.0f) : 0;
+
+ vx += ax * elapsed_time;
+ vy += (ay + grav) * elapsed_time;
+ Vector result(vx * elapsed_time, vy * elapsed_time);
+
+ return result;
+}
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_SUPERTUX_PHYSIC_HPP
+#define HEADER_SUPERTUX_SUPERTUX_PHYSIC_HPP
+
+#include "math/vector.hpp"
+
+/// Physics engine.
+/** This is a very simplistic physics engine handling accelerated and constant
+ * movement along with gravity.
+ */
+class Physic
+{
+public:
+ Physic();
+ ~Physic();
+
+ /// Resets all velocities and accelerations to 0.
+ void reset();
+
+ /// Sets velocity to a fixed value.
+ void set_velocity(float vx, float vy);
+ void set_velocity(const Vector& vector);
+
+ void set_velocity_x(float vx);
+ void set_velocity_y(float vy);
+
+ /// Velocity inversion.
+ void inverse_velocity_x();
+ void inverse_velocity_y();
+
+ Vector get_velocity() const;
+ float get_velocity_x() const;
+ float get_velocity_y() const;
+
+ /// Set acceleration.
+ /** Sets acceleration applied to the object. (Note that gravity is
+ * eventually added to the vertical acceleration)
+ */
+ void set_acceleration(float ax, float ay);
+
+ void set_acceleration_x(float ax);
+ void set_acceleration_y(float ay);
+
+ Vector get_acceleration() const;
+ float get_acceleration_x() const;
+ float get_acceleration_y() const;
+
+ /// Enables or disables handling of gravity.
+ void enable_gravity(bool gravity_enabled);
+ bool gravity_enabled() const;
+
+ /** Set gravity modifier factor to apply to object when enabled */
+ void set_gravity_modifier(float gravity);
+
+ Vector get_movement(float elapsed_time);
+
+private:
+ /** horizontal and vertical acceleration */
+ float ax, ay;
+
+ /** horizontal and vertical velocity */
+ float vx, vy;
+
+ /** should we respect gravity in our calculations? */
+ bool gravity_enabled_flag;
+
+ /** gravity modifier is multiplied with the sectors gravity */
+ float gravity_modifier;
+};
+
+#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2003 Tobias Glaesser <tobi.web@gmx.de>
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include <math.h>
+
+#include "audio/sound_manager.hpp"
+#include "lisp/lisp.hpp"
+#include "util/writer.hpp"
+#include "supertux/main.hpp"
+#include "supertux/player_status.hpp"
+#include "supertux/resources.hpp"
+#include "supertux/timer.hpp"
+#include "video/drawing_context.hpp"
+
+static const int START_COINS = 100;
+static const int MAX_COINS = 9999;
+
+PlayerStatus* player_status = 0;
+
+PlayerStatus::PlayerStatus()
+ : coins(START_COINS),
+ bonus(NO_BONUS),
+ max_fire_bullets(0),
+ max_ice_bullets(0)
+{
+ reset();
+
+ coin_surface.reset(new Surface("images/engine/hud/coins-0.png"));
+ sound_manager->preload("sounds/coin.wav");
+ sound_manager->preload("sounds/lifeup.wav");
+}
+
+PlayerStatus::~PlayerStatus()
+{
+}
+
+void PlayerStatus::reset()
+{
+ coins = START_COINS;
+ bonus = NO_BONUS;
+}
+
+void
+PlayerStatus::add_coins(int count, bool play_sound)
+{
+ static float sound_played_time = 0;
+ coins = std::min(coins + count, MAX_COINS);
+ if(play_sound) {
+ if(count >= 100)
+ sound_manager->play("sounds/lifeup.wav");
+ else if (real_time > sound_played_time + 0.010) {
+ sound_manager->play("sounds/coin.wav");
+ sound_played_time = real_time;
+ }
+ }
+}
+
+void
+PlayerStatus::write(lisp::Writer& writer)
+{
+ switch(bonus) {
+ case NO_BONUS:
+ writer.write("bonus", "none");
+ break;
+ case GROWUP_BONUS:
+ writer.write("bonus", "growup");
+ break;
+ case FIRE_BONUS:
+ writer.write("bonus", "fireflower");
+ break;
+ case ICE_BONUS:
+ writer.write("bonus", "iceflower");
+ break;
+ default:
+ log_warning << "Unknown bonus type." << std::endl;
+ writer.write("bonus", "none");
+ }
+ writer.write("fireflowers", max_fire_bullets);
+ writer.write("iceflowers", max_ice_bullets);
+
+ writer.write("coins", coins);
+}
+
+void
+PlayerStatus::read(const Reader& lisp)
+{
+ reset();
+
+ std::string bonusname;
+ if(lisp.get("bonus", bonusname)) {
+ if(bonusname == "none") {
+ bonus = NO_BONUS;
+ } else if(bonusname == "growup") {
+ bonus = GROWUP_BONUS;
+ } else if(bonusname == "fireflower") {
+ bonus = FIRE_BONUS;
+ } else if(bonusname == "iceflower") {
+ bonus = ICE_BONUS;
+ } else {
+ log_warning << "Unknown bonus '" << bonusname << "' in savefile" << std::endl;
+ bonus = NO_BONUS;
+ }
+ }
+ lisp.get("fireflowers", max_fire_bullets);
+ lisp.get("iceflowers", max_ice_bullets);
+
+ lisp.get("coins", coins);
+}
+
+void
+PlayerStatus::draw(DrawingContext& context)
+{
+ static int displayed_coins = -1;
+ static int next_count = 0;
+
+ if ((displayed_coins == -1) || (fabsf(displayed_coins - coins) > 100)) {
+ displayed_coins = coins;
+ }
+ if (++next_count > 2) {
+ next_count = 0;
+ if (displayed_coins < coins) displayed_coins++;
+ if (displayed_coins > coins) displayed_coins--;
+ }
+ displayed_coins = std::min(std::max(displayed_coins, 0), 9999);
+
+ std::stringstream ss;
+ ss << displayed_coins;
+ std::string coins_text = ss.str();
+
+ context.push_transform();
+ context.set_translation(Vector(0, 0));
+
+ Surface* coin_surf = coin_surface.get();
+ if (coin_surf) {
+ context.draw_surface(coin_surf, Vector(SCREEN_WIDTH - BORDER_X - coin_surf->get_width() - fixed_font->get_text_width(coins_text), BORDER_Y + 1), LAYER_HUD);
+ }
+ context.draw_text(fixed_font, coins_text, Vector(SCREEN_WIDTH - BORDER_X, BORDER_Y), ALIGN_RIGHT, LAYER_HUD, PlayerStatus::text_color);
+
+ context.pop_transform();
+}
+
+void
+PlayerStatus::operator= (const PlayerStatus& other)
+{
+ coins = other.coins;
+ bonus = other.bonus;
+}
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2003 Tobias Glaesser <tobi.web@gmx.de>
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_SUPERTUX_PLAYER_STATUS_HPP
+#define HEADER_SUPERTUX_SUPERTUX_PLAYER_STATUS_HPP
+
+#include <memory>
+
+#include "util/reader_fwd.hpp"
+#include "util/writer_fwd.hpp"
+#include "video/color.hpp"
+
+class Surface;
+
+static const float BORDER_X = 10;
+static const float BORDER_Y = 10;
+
+enum BonusType {
+ NO_BONUS, GROWUP_BONUS, FIRE_BONUS, ICE_BONUS
+};
+class DrawingContext;
+
+/**
+ * This class memorizes player status between different game sessions (for
+ * example when switching maps in the worldmap)
+ */
+class PlayerStatus
+{
+ static Color text_color;
+public:
+ PlayerStatus();
+ ~PlayerStatus();
+ void reset();
+ void add_coins(int count, bool play_sound = true);
+
+ void write(lisp::Writer& writer);
+ void read(const Reader& lisp);
+
+ void draw(DrawingContext& context);
+
+ int coins;
+ BonusType bonus;
+ int max_fire_bullets; /**< maximum number of fire bullets in play */
+ int max_ice_bullets; /**< maximum number of ice bullets in play */
+
+ void operator= (const PlayerStatus& other);
+
+private:
+ // don't use this
+ PlayerStatus(const PlayerStatus& other);
+
+ std::auto_ptr<Surface> coin_surface;
+};
+
+// global player state
+extern PlayerStatus* player_status;
+
+#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2008 Ingo Ruhnke <grumbel@gmx.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include "gui/menu.hpp"
+#include "supertux/gameconfig.hpp"
+#include "util/gettext.hpp"
+
+enum ProfileMenuIDs {
+
+};
+
+class ProfileMenu : public Menu
+{
+public:
+ ProfileMenu() {
+ add_label(_("Select Profile"));
+ add_hl();
+ for(int i = 0; i < 5; ++i)
+ {
+ std::ostringstream out;
+ out << "Profile " << i+1;
+ add_entry(i+1, out.str());
+ }
+
+ add_hl();
+ add_back(_("Back"));
+ }
+
+ void menu_action(MenuItem* item) {
+ g_config->profile = item->id;
+ Menu::set_current(0);
+ }
+};
+
+Menu* profile_menu = 0;
+
+Menu* get_profile_menu()
+{
+ //static ProfileMenu menu;
+ profile_menu = new ProfileMenu();
+ return profile_menu;
+}
+
+void free_profile_menu()
+{
+ delete profile_menu;
+ profile_menu = 0;
+}
+
+/*
+ std::string
+ TitleScreen::get_slotinfo(int slot)
+ {
+ std::string tmp;
+ std::string title;
+
+ std::string basename = current_world->get_basedir();
+ basename = basename.substr(0, basename.length()-1);
+ std::string worlddirname = FileSystem::basename(basename);
+ std::ostringstream stream;
+ stream << "profile" << config->profile << "/" << worlddirname << "_" << slot << ".stsg";
+ std::string slotfile = stream.str();
+
+ try {
+ lisp::Parser parser;
+ const lisp::Lisp* root = parser.parse(slotfile);
+
+ const lisp::Lisp* savegame = root->get_lisp("supertux-savegame");
+ if(!savegame)
+ throw std::runtime_error("file is not a supertux-savegame.");
+
+ savegame->get("title", title);
+ } catch(std::exception& ) {
+ std::ostringstream slottitle;
+ slottitle << _("Slot") << " " << slot << " - " << _("Free");
+ return slottitle.str();
+ }
+
+ std::ostringstream slottitle;
+ slottitle << _("Slot") << " " << slot << " - " << title;
+ return slottitle.str();
+ }
+*/
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2008 Ingo Ruhnke <grumbel@gmx.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_SUPERTUX_PROFILE_MENU_HPP
+#define HEADER_SUPERTUX_SUPERTUX_PROFILE_MENU_HPP
+
+class Menu;
+Menu* get_profile_menu();
+void free_profile_menu();
+
+#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2003 Tobias Glaesser <tobi.web@gmx.de>
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+//#include <config.h>
+
+//#include "supertux/resources.hpp"
+
+#include "gui/mousecursor.hpp"
+#include "sprite/sprite_manager.hpp"
+#include "supertux/player_status.hpp"
+#include "supertux/tile_manager.hpp"
+#include "video/font.hpp"
+
+MouseCursor* mouse_cursor = NULL;
+
+Font* fixed_font = NULL;
+Font* normal_font = NULL;
+Font* small_font = NULL;
+Font* big_font = NULL;
+
+/* Load graphics/sounds shared between all levels: */
+void load_shared()
+{
+ /* Load the mouse-cursor */
+ mouse_cursor = new MouseCursor("images/engine/menu/mousecursor.png");
+ MouseCursor::set_current(mouse_cursor);
+
+ /* Load global images: */
+ fixed_font = new Font(Font::FIXED, "fonts/white.stf");
+ normal_font = new Font(Font::VARIABLE, "fonts/white.stf");
+ small_font = new Font(Font::VARIABLE, "fonts/white-small.stf", 1);
+ big_font = new Font(Font::VARIABLE, "fonts/white-big.stf", 3);
+
+ tile_manager = new TileManager();
+ sprite_manager = new SpriteManager();
+
+ player_status = new PlayerStatus();
+}
+
+/* Free shared data: */
+void unload_shared()
+{
+ /* Free global images: */
+ delete normal_font;
+ delete small_font;
+ delete big_font;
+
+ delete sprite_manager;
+ sprite_manager = NULL;
+
+ /* Free mouse-cursor */
+ delete mouse_cursor;
+
+ delete player_status;
+ player_status = NULL;
+}
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2003 Tobias Glaesser <tobi.web@gmx.de>
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_SUPERTUX_RESOURCES_HPP
+#define HEADER_SUPERTUX_SUPERTUX_RESOURCES_HPP
+
+class Font;
+class MouseCursor;
+
+extern MouseCursor* mouse_cursor;
+
+extern Font* fixed_font;
+extern Font* normal_font;
+extern Font* small_font;
+extern Font* big_font;
+
+void load_shared();
+void unload_shared();
+
+#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_SUPERTUX_SCREEN_HPP
+#define HEADER_SUPERTUX_SUPERTUX_SCREEN_HPP
+
+class DrawingContext;
+
+/**
+ * Abstract base class for code the MainLoop runs exclusively and full-screen.
+ *
+ * Examples of Screens are: The TitleScreen, a WorldMap, a level's
+ * GameSession, a TextScroller, ...
+ */
+class Screen
+{
+public:
+ virtual ~Screen()
+ {}
+
+ /**
+ * gets called before this screen gets activated (which is at least once
+ * before the first draw or update call
+ */
+ virtual void setup()
+ {}
+ /** gets called when the current screen is temporarily suspended */
+ virtual void leave()
+ {}
+
+ /**
+ * gets called once per frame. The screen should draw itself in this function.
+ * State changes should not be done in this function, but rather in update
+ */
+ virtual void draw(DrawingContext& context) = 0;
+
+ /**
+ * gets called for once (per logical) frame. Screens should do their state
+ * updates and logic here
+ */
+ virtual void update(float elapsed_time) = 0;
+};
+
+#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_SUPERTUX_SCREEN_FADE_HPP
+#define HEADER_SUPERTUX_SUPERTUX_SCREEN_FADE_HPP
+
+class DrawingContext;
+
+/**
+ * Screen to be displayed simultaneously with another Screen.
+ *
+ * This is used for Screen transition effects like a fade-out or a shrink-fade
+ */
+class ScreenFade
+{
+public:
+ virtual ~ScreenFade()
+ {}
+
+ /** returns true if the effect is completed */
+ virtual bool done() = 0;
+
+ /** gets called once per frame. The ScreenFade should draw itself in
+ this function. State changes should not be done in this
+ function, but rather in update */
+ virtual void draw(DrawingContext& context) = 0;
+
+ /** gets called for once (per logical) frame. ScreenFades should do
+ their state updates and logic here */
+ virtual void update(float elapsed_time) = 0;
+};
+
+#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_SUPERTUX_SCRIPT_INTERFACE_HPP
+#define HEADER_SUPERTUX_SUPERTUX_SCRIPT_INTERFACE_HPP
+
+#include <squirrel.h>
+
+/**
+ * Objects that want to expose themself to the scripting environment
+ * should implement this interface
+ */
+class ScriptInterface
+{
+public:
+ virtual ~ScriptInterface()
+ {}
+
+ virtual void expose(HSQUIRRELVM vm, SQInteger table_idx) = 0;
+ virtual void unexpose(HSQUIRRELVM vm, SQInteger table_idx) = 0;
+};
+
+#endif
+
+/* EOF */
--- /dev/null
+// SuperTux - A Jump'n Run
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include "supertux/sector.hpp"
+
+#include <algorithm>
+#include <math.h>
+
+#include "audio/sound_manager.hpp"
+#include "badguy/jumpy.hpp"
+#include "lisp/list_iterator.hpp"
+#include "math/aatriangle.hpp"
+#include "object/background.hpp"
+#include "object/bullet.hpp"
+#include "object/camera.hpp"
+#include "object/coin.hpp"
+#include "object/display_effect.hpp"
+#include "object/gradient.hpp"
+#include "object/invisible_block.hpp"
+#include "object/particlesystem.hpp"
+#include "object/particlesystem_interactive.hpp"
+#include "object/player.hpp"
+#include "object/portable.hpp"
+#include "object/pulsing_light.hpp"
+#include "object/smoke_cloud.hpp"
+#include "object/text_object.hpp"
+#include "object/tilemap.hpp"
+#include "physfs/physfs_stream.hpp"
+#include "scripting/squirrel_util.hpp"
+#include "supertux/collision.hpp"
+#include "supertux/constants.hpp"
+#include "supertux/level.hpp"
+#include "supertux/main.hpp"
+#include "supertux/object_factory.hpp"
+#include "supertux/spawn_point.hpp"
+#include "supertux/tile.hpp"
+#include "trigger/sequence_trigger.hpp"
+#include "util/file_system.hpp"
+
+Sector* Sector::_current = 0;
+
+bool Sector::show_collrects = false;
+bool Sector::draw_solids_only = false;
+
+Sector::Sector(Level* parent) :
+ level(parent),
+ currentmusic(LEVEL_MUSIC),
+ ambient_light( 1.0f, 1.0f, 1.0f, 1.0f ),
+ gravity(10.0),
+ player(0),
+ camera(0),
+ effect(0)
+{
+ add_object(new Player(player_status, "Tux"));
+ add_object(new DisplayEffect("Effect"));
+ add_object(new TextObject("Text"));
+
+ sound_manager->preload("sounds/shoot.wav");
+
+ // create a new squirrel table for the sector
+ using namespace Scripting;
+
+ sq_collectgarbage(global_vm);
+
+ sq_newtable(global_vm);
+ sq_pushroottable(global_vm);
+ if(SQ_FAILED(sq_setdelegate(global_vm, -2)))
+ throw Scripting::SquirrelError(global_vm, "Couldn't set sector_table delegate");
+
+ sq_resetobject(§or_table);
+ if(SQ_FAILED(sq_getstackobj(global_vm, -1, §or_table)))
+ throw Scripting::SquirrelError(global_vm, "Couldn't get sector table");
+ sq_addref(global_vm, §or_table);
+ sq_pop(global_vm, 1);
+}
+
+Sector::~Sector()
+{
+ using namespace Scripting;
+
+ deactivate();
+
+ for(ScriptList::iterator i = scripts.begin();
+ i != scripts.end(); ++i) {
+ HSQOBJECT& object = *i;
+ sq_release(global_vm, &object);
+ }
+ sq_release(global_vm, §or_table);
+ sq_collectgarbage(global_vm);
+
+ update_game_objects();
+ assert(gameobjects_new.size() == 0);
+
+ for(GameObjects::iterator i = gameobjects.begin();
+ i != gameobjects.end(); ++i) {
+ GameObject* object = *i;
+ before_object_remove(object);
+ object->unref();
+ }
+
+ for(SpawnPoints::iterator i = spawnpoints.begin(); i != spawnpoints.end();
+ ++i)
+ delete *i;
+}
+
+Level*
+Sector::get_level()
+{
+ return level;
+}
+
+GameObject*
+Sector::parse_object(const std::string& name, const Reader& reader)
+{
+ if(name == "camera") {
+ Camera* camera = new Camera(this, "Camera");
+ camera->parse(reader);
+ return camera;
+ } else if(name == "particles-snow") {
+ SnowParticleSystem* partsys = new SnowParticleSystem();
+ partsys->parse(reader);
+ return partsys;
+ } else if(name == "particles-rain") {
+ RainParticleSystem* partsys = new RainParticleSystem();
+ partsys->parse(reader);
+ return partsys;
+ } else if(name == "particles-comets") {
+ CometParticleSystem* partsys = new CometParticleSystem();
+ partsys->parse(reader);
+ return partsys;
+ } else if(name == "particles-ghosts") {
+ GhostParticleSystem* partsys = new GhostParticleSystem();
+ partsys->parse(reader);
+ return partsys;
+ } else if(name == "particles-clouds") {
+ CloudParticleSystem* partsys = new CloudParticleSystem();
+ partsys->parse(reader);
+ return partsys;
+ } else if(name == "money") { // for compatibility with old maps
+ return new Jumpy(reader);
+ }
+
+ try {
+ return create_object(name, reader);
+ } catch(std::exception& e) {
+ log_warning << e.what() << "" << std::endl;
+ }
+
+ return 0;
+}
+
+void
+Sector::parse(const Reader& sector)
+{
+ bool has_background = false;
+ lisp::ListIterator iter(§or);
+ while(iter.next()) {
+ const std::string& token = iter.item();
+ if(token == "name") {
+ iter.value()->get(name);
+ } else if(token == "gravity") {
+ iter.value()->get(gravity);
+ } else if(token == "music") {
+ iter.value()->get(music);
+ } else if(token == "spawnpoint") {
+ SpawnPoint* sp = new SpawnPoint(iter.lisp());
+ spawnpoints.push_back(sp);
+ } else if(token == "init-script") {
+ iter.value()->get(init_script);
+ } else if(token == "ambient-light") {
+ std::vector<float> vColor;
+ sector.get( "ambient-light", vColor );
+ if(vColor.size() < 3) {
+ log_warning << "(ambient-light) requires a color as argument" << std::endl;
+ } else {
+ ambient_light = Color( vColor );
+ }
+ } else {
+ GameObject* object = parse_object(token, *(iter.lisp()));
+ if(object) {
+ if(dynamic_cast<Background *>(object)) {
+ has_background = true;
+ } else if(dynamic_cast<Gradient *>(object)) {
+ has_background = true;
+ }
+ add_object(object);
+ }
+ }
+ }
+
+ if(!has_background) {
+ Gradient* gradient = new Gradient();
+ gradient->set_gradient(Color(0.3, 0.4, 0.75), Color(1, 1, 1));
+ add_object(gradient);
+ }
+
+ update_game_objects();
+
+ if(solid_tilemaps.size() < 1) log_warning << "sector '" << name << "' does not contain a solid tile layer." << std::endl;
+
+ fix_old_tiles();
+ if(!camera) {
+ log_warning << "sector '" << name << "' does not contain a camera." << std::endl;
+ update_game_objects();
+ add_object(new Camera(this, "Camera"));
+ }
+
+ update_game_objects();
+}
+
+void
+Sector::parse_old_format(const Reader& reader)
+{
+ name = "main";
+ reader.get("gravity", gravity);
+
+ std::string backgroundimage;
+ if (reader.get("background", backgroundimage) && (backgroundimage != "")) {
+ if (backgroundimage == "arctis.png") backgroundimage = "arctis.jpg";
+ if (backgroundimage == "arctis2.jpg") backgroundimage = "arctis.jpg";
+ if (backgroundimage == "ocean.png") backgroundimage = "ocean.jpg";
+ backgroundimage = "images/background/" + backgroundimage;
+ if (!PHYSFS_exists(backgroundimage.c_str())) {
+ log_warning << "Background image \"" << backgroundimage << "\" not found. Ignoring." << std::endl;
+ backgroundimage = "";
+ }
+ }
+
+ float bgspeed = .5;
+ reader.get("bkgd_speed", bgspeed);
+ bgspeed /= 100;
+
+ Color bkgd_top, bkgd_bottom;
+ int r = 0, g = 0, b = 128;
+ reader.get("bkgd_red_top", r);
+ reader.get("bkgd_green_top", g);
+ reader.get("bkgd_blue_top", b);
+ bkgd_top.red = static_cast<float> (r) / 255.0f;
+ bkgd_top.green = static_cast<float> (g) / 255.0f;
+ bkgd_top.blue = static_cast<float> (b) / 255.0f;
+
+ reader.get("bkgd_red_bottom", r);
+ reader.get("bkgd_green_bottom", g);
+ reader.get("bkgd_blue_bottom", b);
+ bkgd_bottom.red = static_cast<float> (r) / 255.0f;
+ bkgd_bottom.green = static_cast<float> (g) / 255.0f;
+ bkgd_bottom.blue = static_cast<float> (b) / 255.0f;
+
+ if(backgroundimage != "") {
+ Background* background = new Background();
+ background->set_image(backgroundimage, bgspeed);
+ add_object(background);
+ } else {
+ Gradient* gradient = new Gradient();
+ gradient->set_gradient(bkgd_top, bkgd_bottom);
+ add_object(gradient);
+ }
+
+ std::string particlesystem;
+ reader.get("particle_system", particlesystem);
+ if(particlesystem == "clouds")
+ add_object(new CloudParticleSystem());
+ else if(particlesystem == "snow")
+ add_object(new SnowParticleSystem());
+ else if(particlesystem == "rain")
+ add_object(new RainParticleSystem());
+
+ Vector startpos(100, 170);
+ reader.get("start_pos_x", startpos.x);
+ reader.get("start_pos_y", startpos.y);
+
+ SpawnPoint* spawn = new SpawnPoint;
+ spawn->pos = startpos;
+ spawn->name = "main";
+ spawnpoints.push_back(spawn);
+
+ music = "chipdisko.ogg";
+ // skip reading music filename. It's all .ogg now, anyway
+ /*
+ reader.get("music", music);
+ */
+ music = "music/" + music;
+
+ int width = 30, height = 15;
+ reader.get("width", width);
+ reader.get("height", height);
+
+ std::vector<unsigned int> tiles;
+ if(reader.get("interactive-tm", tiles)
+ || reader.get("tilemap", tiles)) {
+ TileMap* tilemap = new TileMap(level->get_tileset());
+ tilemap->set(width, height, tiles, LAYER_TILES, true);
+
+ // replace tile id 112 (old invisible tile) with 1311 (new invisible tile)
+ for(size_t x=0; x < tilemap->get_width(); ++x) {
+ for(size_t y=0; y < tilemap->get_height(); ++y) {
+ uint32_t id = tilemap->get_tile_id(x, y);
+ if(id == 112)
+ tilemap->change(x, y, 1311);
+ }
+ }
+
+ if (height < 19) tilemap->resize(width, 19);
+ add_object(tilemap);
+ }
+
+ if(reader.get("background-tm", tiles)) {
+ TileMap* tilemap = new TileMap(level->get_tileset());
+ tilemap->set(width, height, tiles, LAYER_BACKGROUNDTILES, false);
+ if (height < 19) tilemap->resize(width, 19);
+ add_object(tilemap);
+ }
+
+ if(reader.get("foreground-tm", tiles)) {
+ TileMap* tilemap = new TileMap(level->get_tileset());
+ tilemap->set(width, height, tiles, LAYER_FOREGROUNDTILES, false);
+
+ // fill additional space in foreground with tiles of ID 2035 (lightmap/black)
+ if (height < 19) tilemap->resize(width, 19, 2035);
+
+ add_object(tilemap);
+ }
+
+ // read reset-points (now spawn-points)
+ const lisp::Lisp* resetpoints = reader.get_lisp("reset-points");
+ if(resetpoints) {
+ lisp::ListIterator iter(resetpoints);
+ while(iter.next()) {
+ if(iter.item() == "point") {
+ Vector sp_pos;
+ if(reader.get("x", sp_pos.x) && reader.get("y", sp_pos.y))
+ {
+ SpawnPoint* sp = new SpawnPoint;
+ sp->name = "main";
+ sp->pos = sp_pos;
+ spawnpoints.push_back(sp);
+ }
+ } else {
+ log_warning << "Unknown token '" << iter.item() << "' in reset-points." << std::endl;
+ }
+ }
+ }
+
+ // read objects
+ const lisp::Lisp* objects = reader.get_lisp("objects");
+ if(objects) {
+ lisp::ListIterator iter(objects);
+ while(iter.next()) {
+ GameObject* object = parse_object(iter.item(), *(iter.lisp()));
+ if(object) {
+ add_object(object);
+ } else {
+ log_warning << "Unknown object '" << iter.item() << "' in level." << std::endl;
+ }
+ }
+ }
+
+ // add a camera
+ Camera* camera = new Camera(this, "Camera");
+ add_object(camera);
+
+ update_game_objects();
+
+ if(solid_tilemaps.size() < 1) log_warning << "sector '" << name << "' does not contain a solid tile layer." << std::endl;
+
+ fix_old_tiles();
+ update_game_objects();
+}
+
+void
+Sector::fix_old_tiles()
+{
+ for(std::list<TileMap*>::iterator i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
+ TileMap* solids = *i;
+ for(size_t x=0; x < solids->get_width(); ++x) {
+ for(size_t y=0; y < solids->get_height(); ++y) {
+ uint32_t id = solids->get_tile_id(x, y);
+ const Tile *tile = solids->get_tile(x, y);
+ Vector pos(solids->get_x_offset() + x*32, solids->get_y_offset() + y*32);
+
+ if(id == 112) {
+ add_object(new InvisibleBlock(pos));
+ solids->change(x, y, 0);
+ } else if(tile->getAttributes() & Tile::COIN) {
+ add_object(new Coin(pos));
+ solids->change(x, y, 0);
+ } else if(tile->getAttributes() & Tile::FULLBOX) {
+ add_object(new BonusBlock(pos, tile->getData()));
+ solids->change(x, y, 0);
+ } else if(tile->getAttributes() & Tile::BRICK) {
+ add_object(new Brick(pos, tile->getData()));
+ solids->change(x, y, 0);
+ } else if(tile->getAttributes() & Tile::GOAL) {
+ std::string sequence = tile->getData() == 0 ? "endsequence" : "stoptux";
+ add_object(new SequenceTrigger(pos, sequence));
+ solids->change(x, y, 0);
+ }
+ }
+ }
+ }
+
+ // add lights for special tiles
+ for(GameObjects::iterator i = gameobjects.begin(); i != gameobjects.end(); i++) {
+ TileMap* tm = dynamic_cast<TileMap*>(*i);
+ if (!tm) continue;
+ for(size_t x=0; x < tm->get_width(); ++x) {
+ for(size_t y=0; y < tm->get_height(); ++y) {
+ uint32_t id = tm->get_tile_id(x, y);
+ Vector pos(tm->get_x_offset() + x*32, tm->get_y_offset() + y*32);
+ Vector center(pos.x + 16, pos.y + 16);
+
+ // torch
+ if (id == 1517) {
+ float pseudo_rnd = (float)((int)pos.x % 10) / 10;
+ add_object(new PulsingLight(center, 1.0f + pseudo_rnd, 0.9f, 1.0f, Color(1.0f, 1.0f, 0.6f, 1.0f)));
+ }
+ // lava or lavaflow
+ if ((id == 173) || (id == 1700) || (id == 1705) || (id == 1706)) {
+ // space lights a bit
+ if ((((tm->get_tile_id(x-1, y)) != tm->get_tile_id(x,y))
+ && (tm->get_tile_id(x, y-1) != tm->get_tile_id(x,y)))
+ || ((x % 3 == 0) && (y % 3 == 0))) {
+ float pseudo_rnd = (float)((int)pos.x % 10) / 10;
+ add_object(new PulsingLight(center, 1.0f + pseudo_rnd, 0.8f, 1.0f, Color(1.0f, 0.3f, 0.0f, 1.0f)));
+ }
+ }
+
+ }
+ }
+ }
+
+}
+
+HSQUIRRELVM
+Sector::run_script(std::istream& in, const std::string& sourcename)
+{
+ using namespace Scripting;
+
+ // garbage collect thread list
+ for(ScriptList::iterator i = scripts.begin();
+ i != scripts.end(); ) {
+ HSQOBJECT& object = *i;
+ HSQUIRRELVM vm = object_to_vm(object);
+
+ if(sq_getvmstate(vm) != SQ_VMSTATE_SUSPENDED) {
+ sq_release(global_vm, &object);
+ i = scripts.erase(i);
+ continue;
+ }
+
+ ++i;
+ }
+
+ HSQOBJECT object = create_thread(global_vm);
+ scripts.push_back(object);
+
+ HSQUIRRELVM vm = object_to_vm(object);
+
+ // set sector_table as roottable for the thread
+ sq_pushobject(vm, sector_table);
+ sq_setroottable(vm);
+
+ try {
+ compile_and_run(vm, in, "Sector " + name + " - " + sourcename);
+ } catch(std::exception& e) {
+ log_warning << "Error running script: " << e.what() << std::endl;
+ }
+
+ return vm;
+}
+
+void
+Sector::add_object(GameObject* object)
+{
+ // make sure the object isn't already in the list
+#ifdef DEBUG
+ for(GameObjects::iterator i = gameobjects.begin(); i != gameobjects.end();
+ ++i) {
+ if(*i == object) {
+ assert("object already added to sector" == 0);
+ }
+ }
+ for(GameObjects::iterator i = gameobjects_new.begin();
+ i != gameobjects_new.end(); ++i) {
+ if(*i == object) {
+ assert("object already added to sector" == 0);
+ }
+ }
+#endif
+
+ object->ref();
+ gameobjects_new.push_back(object);
+}
+
+void
+Sector::activate(const std::string& spawnpoint)
+{
+ SpawnPoint* sp = 0;
+ for(SpawnPoints::iterator i = spawnpoints.begin(); i != spawnpoints.end();
+ ++i) {
+ if((*i)->name == spawnpoint) {
+ sp = *i;
+ break;
+ }
+ }
+ if(!sp) {
+ log_warning << "Spawnpoint '" << spawnpoint << "' not found." << std::endl;
+ if(spawnpoint != "main") {
+ activate("main");
+ } else {
+ activate(Vector(0, 0));
+ }
+ } else {
+ activate(sp->pos);
+ }
+}
+
+void
+Sector::activate(const Vector& player_pos)
+{
+ if(_current != this) {
+ if(_current != NULL)
+ _current->deactivate();
+ _current = this;
+
+ // register sectortable as sector in scripting
+ HSQUIRRELVM vm = Scripting::global_vm;
+ sq_pushroottable(vm);
+ sq_pushstring(vm, "sector", -1);
+ sq_pushobject(vm, sector_table);
+ if(SQ_FAILED(sq_createslot(vm, -3)))
+ throw Scripting::SquirrelError(vm, "Couldn't set sector in roottable");
+ sq_pop(vm, 1);
+
+ for(GameObjects::iterator i = gameobjects.begin();
+ i != gameobjects.end(); ++i) {
+ GameObject* object = *i;
+
+ try_expose(object);
+ }
+ }
+ try_expose_me();
+
+ // spawn smalltux below spawnpoint
+ if (!player->is_big()) {
+ player->move(player_pos + Vector(0,32));
+ } else {
+ player->move(player_pos);
+ }
+
+ // spawning tux in the ground would kill him
+ if(!is_free_of_tiles(player->get_bbox())) {
+ log_warning << "Tried spawning Tux in solid matter. Compensating." << std::endl;
+ Vector npos = player->get_bbox().p1;
+ npos.y-=32;
+ player->move(npos);
+ }
+
+ camera->reset(player->get_pos());
+ update_game_objects();
+
+ //Run default.nut just before init script
+ //Check to see if it's in a levelset (info file)
+ std::string basedir = FileSystem::dirname(get_level()->filename);
+ if(PHYSFS_exists((basedir + "/info").c_str())) {
+ try {
+ IFileStream in(basedir + "/default.nut");
+ run_script(in, "default.nut");
+ } catch(std::exception& ) {
+ // doesn't exist or erroneous; do nothing
+ }
+ }
+
+ // Run init script
+ if(init_script != "") {
+ std::istringstream in(init_script);
+ run_script(in, "init-script");
+ }
+}
+
+void
+Sector::deactivate()
+{
+ if(_current != this)
+ return;
+
+ // remove sector entry from global vm
+ HSQUIRRELVM vm = Scripting::global_vm;
+ sq_pushroottable(vm);
+ sq_pushstring(vm, "sector", -1);
+ if(SQ_FAILED(sq_deleteslot(vm, -2, SQFalse)))
+ throw Scripting::SquirrelError(vm, "Couldn't unset sector in roottable");
+ sq_pop(vm, 1);
+
+ for(GameObjects::iterator i = gameobjects.begin();
+ i != gameobjects.end(); ++i) {
+ GameObject* object = *i;
+
+ try_unexpose(object);
+ }
+
+ try_unexpose_me();
+ _current = NULL;
+}
+
+Rect
+Sector::get_active_region()
+{
+ return Rect(
+ camera->get_translation() - Vector(1600, 1200),
+ camera->get_translation() + Vector(1600, 1200) + Vector(SCREEN_WIDTH,SCREEN_HEIGHT));
+}
+
+void
+Sector::update(float elapsed_time)
+{
+ player->check_bounds(camera);
+
+ /* update objects */
+ for(GameObjects::iterator i = gameobjects.begin();
+ i != gameobjects.end(); ++i) {
+ GameObject* object = *i;
+ if(!object->is_valid())
+ continue;
+
+ object->update(elapsed_time);
+ }
+
+ /* Handle all possible collisions. */
+ handle_collisions();
+ update_game_objects();
+}
+
+void
+Sector::update_game_objects()
+{
+ /** cleanup marked objects */
+ for(std::vector<GameObject*>::iterator i = gameobjects.begin();
+ i != gameobjects.end(); /* nothing */) {
+ GameObject* object = *i;
+
+ if(object->is_valid()) {
+ ++i;
+ continue;
+ }
+
+ before_object_remove(object);
+
+ object->unref();
+ i = gameobjects.erase(i);
+ }
+
+ /* add newly created objects */
+ for(std::vector<GameObject*>::iterator i = gameobjects_new.begin();
+ i != gameobjects_new.end(); ++i)
+ {
+ GameObject* object = *i;
+
+ before_object_add(object);
+
+ gameobjects.push_back(object);
+ }
+ gameobjects_new.clear();
+
+ /* update solid_tilemaps list */
+ //FIXME: this could be more efficient
+ solid_tilemaps.clear();
+ for(std::vector<GameObject*>::iterator i = gameobjects.begin();
+ i != gameobjects.end(); ++i)
+ {
+ TileMap* tm = dynamic_cast<TileMap*>(*i);
+ if (!tm) continue;
+ if (tm->is_solid()) solid_tilemaps.push_back(tm);
+ }
+
+}
+
+bool
+Sector::before_object_add(GameObject* object)
+{
+ Bullet* bullet = dynamic_cast<Bullet*> (object);
+ if(bullet != NULL) {
+ bullets.push_back(bullet);
+ }
+
+ MovingObject* movingobject = dynamic_cast<MovingObject*> (object);
+ if(movingobject != NULL) {
+ moving_objects.push_back(movingobject);
+ }
+
+ Portable* portable = dynamic_cast<Portable*> (object);
+ if(portable != NULL) {
+ portables.push_back(portable);
+ }
+
+ TileMap* tilemap = dynamic_cast<TileMap*> (object);
+ if(tilemap != NULL && tilemap->is_solid()) {
+ solid_tilemaps.push_back(tilemap);
+ }
+
+ Camera* camera = dynamic_cast<Camera*> (object);
+ if(camera != NULL) {
+ if(this->camera != 0) {
+ log_warning << "Multiple cameras added. Ignoring" << std::endl;
+ return false;
+ }
+ this->camera = camera;
+ }
+
+ Player* player = dynamic_cast<Player*> (object);
+ if(player != NULL) {
+ if(this->player != 0) {
+ log_warning << "Multiple players added. Ignoring" << std::endl;
+ return false;
+ }
+ this->player = player;
+ }
+
+ DisplayEffect* effect = dynamic_cast<DisplayEffect*> (object);
+ if(effect != NULL) {
+ if(this->effect != 0) {
+ log_warning << "Multiple DisplayEffects added. Ignoring" << std::endl;
+ return false;
+ }
+ this->effect = effect;
+ }
+
+ if(_current == this) {
+ try_expose(object);
+ }
+
+ return true;
+}
+
+void
+Sector::try_expose(GameObject* object)
+{
+ ScriptInterface* interface = dynamic_cast<ScriptInterface*> (object);
+ if(interface != NULL) {
+ HSQUIRRELVM vm = Scripting::global_vm;
+ sq_pushobject(vm, sector_table);
+ interface->expose(vm, -1);
+ sq_pop(vm, 1);
+ }
+}
+
+void
+Sector::try_expose_me()
+{
+ HSQUIRRELVM vm = Scripting::global_vm;
+ sq_pushobject(vm, sector_table);
+ Scripting::SSector* interface = static_cast<Scripting::SSector*> (this);
+ expose_object(vm, -1, interface, "settings", false);
+ sq_pop(vm, 1);
+}
+
+void
+Sector::before_object_remove(GameObject* object)
+{
+ Portable* portable = dynamic_cast<Portable*> (object);
+ if(portable != NULL) {
+ portables.erase(std::find(portables.begin(), portables.end(), portable));
+ }
+ Bullet* bullet = dynamic_cast<Bullet*> (object);
+ if(bullet != NULL) {
+ bullets.erase(std::find(bullets.begin(), bullets.end(), bullet));
+ }
+ MovingObject* moving_object = dynamic_cast<MovingObject*> (object);
+ if(moving_object != NULL) {
+ moving_objects.erase(
+ std::find(moving_objects.begin(), moving_objects.end(), moving_object));
+ }
+
+ if(_current == this)
+ try_unexpose(object);
+}
+
+void
+Sector::try_unexpose(GameObject* object)
+{
+ ScriptInterface* interface = dynamic_cast<ScriptInterface*> (object);
+ if(interface != NULL) {
+ HSQUIRRELVM vm = Scripting::global_vm;
+ SQInteger oldtop = sq_gettop(vm);
+ sq_pushobject(vm, sector_table);
+ try {
+ interface->unexpose(vm, -1);
+ } catch(std::exception& e) {
+ log_warning << "Couldn't unregister object: " << e.what() << std::endl;
+ }
+ sq_settop(vm, oldtop);
+ }
+}
+
+void
+Sector::try_unexpose_me()
+{
+ HSQUIRRELVM vm = Scripting::global_vm;
+ SQInteger oldtop = sq_gettop(vm);
+ sq_pushobject(vm, sector_table);
+ try {
+ Scripting::unexpose_object(vm, -1, "settings");
+ } catch(std::exception& e) {
+ log_warning << "Couldn't unregister object: " << e.what() << std::endl;
+ }
+ sq_settop(vm, oldtop);
+}
+void
+Sector::draw(DrawingContext& context)
+{
+ context.set_ambient_color( ambient_light );
+ context.push_transform();
+ context.set_translation(camera->get_translation());
+
+ for(GameObjects::iterator i = gameobjects.begin();
+ i != gameobjects.end(); ++i) {
+ GameObject* object = *i;
+ if(!object->is_valid())
+ continue;
+
+ if (draw_solids_only)
+ {
+ TileMap* tm = dynamic_cast<TileMap*>(object);
+ if (tm && !tm->is_solid())
+ continue;
+ }
+
+ object->draw(context);
+ }
+
+ if(show_collrects) {
+ Color col(0.2f, 0.2f, 0.2f, 0.7f);
+ for(MovingObjects::iterator i = moving_objects.begin();
+ i != moving_objects.end(); ++i) {
+ MovingObject* object = *i;
+ const Rect& rect = object->get_bbox();
+
+ context.draw_filled_rect(rect, col, LAYER_FOREGROUND1 + 10);
+ }
+ }
+
+ context.pop_transform();
+}
+
+/*-------------------------------------------------------------------------
+ * Collision Detection
+ *-------------------------------------------------------------------------*/
+
+/** r1 is supposed to be moving, r2 a solid object */
+void check_collisions(collision::Constraints* constraints,
+ const Vector& movement, const Rect& r1, const Rect& r2,
+ GameObject* object = NULL, MovingObject* other = NULL, const Vector& addl_ground_movement = Vector(0,0))
+{
+ if(!collision::intersects(r1, r2))
+ return;
+
+ MovingObject *moving_object = dynamic_cast<MovingObject*> (object);
+ CollisionHit dummy;
+ if(other != NULL && !other->collides(*object, dummy))
+ return;
+ if(moving_object != NULL && !moving_object->collides(*other, dummy))
+ return;
+
+ // calculate intersection
+ float itop = r1.get_bottom() - r2.get_top();
+ float ibottom = r2.get_bottom() - r1.get_top();
+ float ileft = r1.get_right() - r2.get_left();
+ float iright = r2.get_right() - r1.get_left();
+
+ if(fabsf(movement.y) > fabsf(movement.x)) {
+ if(ileft < SHIFT_DELTA) {
+ constraints->right = std::min(constraints->right, r2.get_left());
+ return;
+ } else if(iright < SHIFT_DELTA) {
+ constraints->left = std::max(constraints->left, r2.get_right());
+ return;
+ }
+ } else {
+ // shiftout bottom/top
+ if(itop < SHIFT_DELTA) {
+ constraints->bottom = std::min(constraints->bottom, r2.get_top());
+ return;
+ } else if(ibottom < SHIFT_DELTA) {
+ constraints->top = std::max(constraints->top, r2.get_bottom());
+ return;
+ }
+ }
+
+ constraints->ground_movement += addl_ground_movement;
+ if(other != NULL) {
+ HitResponse response = other->collision(*object, dummy);
+ if(response == PASSTHROUGH)
+ return;
+
+ if(other->get_movement() != Vector(0, 0)) {
+ // TODO what todo when we collide with 2 moving objects?!?
+ constraints->ground_movement = other->get_movement();
+ }
+ }
+
+ float vert_penetration = std::min(itop, ibottom);
+ float horiz_penetration = std::min(ileft, iright);
+ if(vert_penetration < horiz_penetration) {
+ if(itop < ibottom) {
+ constraints->bottom = std::min(constraints->bottom, r2.get_top());
+ constraints->hit.bottom = true;
+ } else {
+ constraints->top = std::max(constraints->top, r2.get_bottom());
+ constraints->hit.top = true;
+ }
+ } else {
+ if(ileft < iright) {
+ constraints->right = std::min(constraints->right, r2.get_left());
+ constraints->hit.right = true;
+ } else {
+ constraints->left = std::max(constraints->left, r2.get_right());
+ constraints->hit.left = true;
+ }
+ }
+}
+
+void
+Sector::collision_tilemap(collision::Constraints* constraints,
+ const Vector& movement, const Rect& dest) const
+{
+ // calculate rectangle where the object will move
+ float x1 = dest.get_left();
+ float x2 = dest.get_right();
+ float y1 = dest.get_top();
+ float y2 = dest.get_bottom();
+
+ for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
+ TileMap* solids = *i;
+
+ // test with all tiles in this rectangle
+ int starttilex = int(x1 - solids->get_x_offset()) / 32;
+ int starttiley = int(y1 - solids->get_y_offset()) / 32;
+ int max_x = int(x2 - solids->get_x_offset());
+ int max_y = int(y2+1 - solids->get_y_offset());
+
+ for(int x = starttilex; x*32 < max_x; ++x) {
+ for(int y = starttiley; y*32 < max_y; ++y) {
+ const Tile* tile = solids->get_tile(x, y);
+ if(!tile)
+ continue;
+ // skip non-solid tiles
+ if((tile->getAttributes() & Tile::SOLID) == 0)
+ continue;
+ // only handle unisolid when the player is falling down and when he was
+ // above the tile before
+ if(tile->getAttributes() & Tile::UNISOLID) {
+ if(movement.y <= 0 || dest.get_bottom() - movement.y - SHIFT_DELTA > y*32)
+ continue;
+ }
+
+ if(tile->getAttributes() & Tile::SLOPE) { // slope tile
+ AATriangle triangle;
+ Vector p1(x*32 + solids->get_x_offset(), y*32 + solids->get_y_offset());
+ Vector p2((x+1)*32 + solids->get_x_offset(), (y+1)*32 + solids->get_y_offset());
+ triangle = AATriangle(p1, p2, tile->getData());
+
+ collision::rectangle_aatriangle(constraints, dest, triangle, solids->get_movement());
+ } else { // normal rectangular tile
+ Rect rect(x*32 + solids->get_x_offset(), y*32 + solids->get_y_offset(), (x+1)*32 + solids->get_x_offset(), (y+1)*32 + solids->get_y_offset());
+ check_collisions(constraints, movement, dest, rect, NULL, NULL, solids->get_movement());
+ }
+ }
+ }
+ }
+}
+
+uint32_t
+Sector::collision_tile_attributes(const Rect& dest) const
+{
+ float x1 = dest.p1.x;
+ float y1 = dest.p1.y;
+ float x2 = dest.p2.x;
+ float y2 = dest.p2.y + SHIFT_DELTA;
+
+ uint32_t result = 0;
+ for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
+ TileMap* solids = *i;
+
+ // test with all tiles in this rectangle
+ int starttilex = int(x1 - solids->get_x_offset()) / 32;
+ int starttiley = int(y1 - solids->get_y_offset()) / 32;
+ int max_x = int(x2 - solids->get_x_offset());
+ int max_y = int(y2+1 - solids->get_y_offset());
+
+ for(int x = starttilex; x*32 < max_x; ++x) {
+ for(int y = starttiley; y*32 < max_y; ++y) {
+ const Tile* tile = solids->get_tile(x, y);
+ if(!tile)
+ continue;
+ result |= tile->getAttributes();
+ }
+ }
+ }
+
+ return result;
+}
+
+/** fills in CollisionHit and Normal vector of 2 intersecting rectangle */
+static void get_hit_normal(const Rect& r1, const Rect& r2, CollisionHit& hit,
+ Vector& normal)
+{
+ float itop = r1.get_bottom() - r2.get_top();
+ float ibottom = r2.get_bottom() - r1.get_top();
+ float ileft = r1.get_right() - r2.get_left();
+ float iright = r2.get_right() - r1.get_left();
+
+ float vert_penetration = std::min(itop, ibottom);
+ float horiz_penetration = std::min(ileft, iright);
+ if(vert_penetration < horiz_penetration) {
+ if(itop < ibottom) {
+ hit.bottom = true;
+ normal.y = vert_penetration;
+ } else {
+ hit.top = true;
+ normal.y = -vert_penetration;
+ }
+ } else {
+ if(ileft < iright) {
+ hit.right = true;
+ normal.x = horiz_penetration;
+ } else {
+ hit.left = true;
+ normal.x = -horiz_penetration;
+ }
+ }
+}
+
+void
+Sector::collision_object(MovingObject* object1, MovingObject* object2) const
+{
+ using namespace collision;
+
+ const Rect& r1 = object1->dest;
+ const Rect& r2 = object2->dest;
+
+ CollisionHit hit;
+ if(intersects(object1->dest, object2->dest)) {
+ Vector normal;
+ get_hit_normal(r1, r2, hit, normal);
+
+ if(!object1->collides(*object2, hit))
+ return;
+ std::swap(hit.left, hit.right);
+ std::swap(hit.top, hit.bottom);
+ if(!object2->collides(*object1, hit))
+ return;
+ std::swap(hit.left, hit.right);
+ std::swap(hit.top, hit.bottom);
+
+ HitResponse response1 = object1->collision(*object2, hit);
+ std::swap(hit.left, hit.right);
+ std::swap(hit.top, hit.bottom);
+ HitResponse response2 = object2->collision(*object1, hit);
+ if(response1 == CONTINUE && response2 == CONTINUE) {
+ normal *= (0.5 + DELTA);
+ object1->dest.move(-normal);
+ object2->dest.move(normal);
+ } else if (response1 == CONTINUE && response2 == FORCE_MOVE) {
+ normal *= (1 + DELTA);
+ object1->dest.move(-normal);
+ } else if (response1 == FORCE_MOVE && response2 == CONTINUE) {
+ normal *= (1 + DELTA);
+ object2->dest.move(normal);
+ }
+ }
+}
+
+void
+Sector::collision_static(collision::Constraints* constraints,
+ const Vector& movement, const Rect& dest,
+ GameObject& object)
+{
+ collision_tilemap(constraints, movement, dest);
+
+ // collision with other (static) objects
+ for(MovingObjects::iterator i = moving_objects.begin();
+ i != moving_objects.end(); ++i) {
+ MovingObject* moving_object = *i;
+ if(moving_object->get_group() != COLGROUP_STATIC
+ && moving_object->get_group() != COLGROUP_MOVING_STATIC)
+ continue;
+ if(!moving_object->is_valid())
+ continue;
+
+ if(moving_object != &object)
+ check_collisions(constraints, movement, dest, moving_object->bbox,
+ &object, moving_object);
+ }
+}
+
+void
+Sector::collision_static_constrains(MovingObject& object)
+{
+ using namespace collision;
+ float infinity = (std::numeric_limits<float>::has_infinity ? std::numeric_limits<float>::infinity() : std::numeric_limits<float>::max());
+
+ Constraints constraints;
+ Vector movement = object.get_movement();
+ Rect& dest = object.dest;
+ float owidth = object.get_bbox().get_width();
+ float oheight = object.get_bbox().get_height();
+
+ for(int i = 0; i < 2; ++i) {
+ collision_static(&constraints, Vector(0, movement.y), dest, object);
+ if(!constraints.has_constraints())
+ break;
+
+ // apply calculated horizontal constraints
+ if(constraints.bottom < infinity) {
+ float height = constraints.bottom - constraints.top;
+ if(height < oheight) {
+ // we're crushed, but ignore this for now, we'll get this again
+ // later if we're really crushed or things will solve itself when
+ // looking at the vertical constraints
+ }
+ dest.p2.y = constraints.bottom - DELTA;
+ dest.p1.y = dest.p2.y - oheight;
+ } else if(constraints.top > -infinity) {
+ dest.p1.y = constraints.top + DELTA;
+ dest.p2.y = dest.p1.y + oheight;
+ }
+ }
+ if(constraints.has_constraints()) {
+ if(constraints.hit.bottom) {
+ dest.move(constraints.ground_movement);
+ }
+ if(constraints.hit.top || constraints.hit.bottom) {
+ constraints.hit.left = false;
+ constraints.hit.right = false;
+ object.collision_solid(constraints.hit);
+ }
+ }
+
+ constraints = Constraints();
+ for(int i = 0; i < 2; ++i) {
+ collision_static(&constraints, movement, dest, object);
+ if(!constraints.has_constraints())
+ break;
+
+ // apply calculated vertical constraints
+ if(constraints.right < infinity) {
+ float width = constraints.right - constraints.left;
+ if(width + SHIFT_DELTA < owidth) {
+#if 0
+ printf("Object %p crushed horizontally... L:%f R:%f\n", &object,
+ constraints.left, constraints.right);
+#endif
+ CollisionHit h;
+ h.left = true;
+ h.right = true;
+ h.crush = true;
+ object.collision_solid(h);
+ } else {
+ dest.p2.x = constraints.right - DELTA;
+ dest.p1.x = dest.p2.x - owidth;
+ }
+ } else if(constraints.left > -infinity) {
+ dest.p1.x = constraints.left + DELTA;
+ dest.p2.x = dest.p1.x + owidth;
+ }
+ }
+
+ if(constraints.has_constraints()) {
+ if( constraints.hit.left || constraints.hit.right
+ || constraints.hit.top || constraints.hit.bottom
+ || constraints.hit.crush )
+ object.collision_solid(constraints.hit);
+ }
+
+ // an extra pass to make sure we're not crushed horizontally
+ constraints = Constraints();
+ collision_static(&constraints, movement, dest, object);
+ if(constraints.bottom < infinity) {
+ float height = constraints.bottom - constraints.top;
+ if(height + SHIFT_DELTA < oheight) {
+#if 0
+ printf("Object %p crushed vertically...\n", &object);
+#endif
+ CollisionHit h;
+ h.top = true;
+ h.bottom = true;
+ h.crush = true;
+ object.collision_solid(h);
+ }
+ }
+}
+
+namespace {
+const float MAX_SPEED = 16.0f;
+}
+
+void
+Sector::handle_collisions()
+{
+ using namespace collision;
+
+ // calculate destination positions of the objects
+ for(MovingObjects::iterator i = moving_objects.begin();
+ i != moving_objects.end(); ++i) {
+ MovingObject* moving_object = *i;
+ Vector mov = moving_object->get_movement();
+
+ // make sure movement is never faster than MAX_SPEED. Norm is pretty fat, so two addl. checks are done before.
+ if (((mov.x > MAX_SPEED * M_SQRT1_2) || (mov.y > MAX_SPEED * M_SQRT1_2)) && (mov.norm() > MAX_SPEED)) {
+ moving_object->movement = mov.unit() * MAX_SPEED;
+ //log_debug << "Temporarily reduced object's speed of " << mov.norm() << " to " << moving_object->movement.norm() << "." << std::endl;
+ }
+
+ moving_object->dest = moving_object->get_bbox();
+ moving_object->dest.move(moving_object->get_movement());
+ }
+
+ // part1: COLGROUP_MOVING vs COLGROUP_STATIC and tilemap
+ for(MovingObjects::iterator i = moving_objects.begin();
+ i != moving_objects.end(); ++i) {
+ MovingObject* moving_object = *i;
+ if((moving_object->get_group() != COLGROUP_MOVING
+ && moving_object->get_group() != COLGROUP_MOVING_STATIC
+ && moving_object->get_group() != COLGROUP_MOVING_ONLY_STATIC)
+ || !moving_object->is_valid())
+ continue;
+
+ collision_static_constrains(*moving_object);
+ }
+
+ // part2: COLGROUP_MOVING vs tile attributes
+ for(MovingObjects::iterator i = moving_objects.begin();
+ i != moving_objects.end(); ++i) {
+ MovingObject* moving_object = *i;
+ if((moving_object->get_group() != COLGROUP_MOVING
+ && moving_object->get_group() != COLGROUP_MOVING_STATIC
+ && moving_object->get_group() != COLGROUP_MOVING_ONLY_STATIC)
+ || !moving_object->is_valid())
+ continue;
+
+ uint32_t tile_attributes = collision_tile_attributes(moving_object->dest);
+ if(tile_attributes > Tile::FIRST_INTERESTING_FLAG) {
+ moving_object->collision_tile(tile_attributes);
+ }
+ }
+
+ // part2.5: COLGROUP_MOVING vs COLGROUP_TOUCHABLE
+ for(MovingObjects::iterator i = moving_objects.begin();
+ i != moving_objects.end(); ++i) {
+ MovingObject* moving_object = *i;
+ if((moving_object->get_group() != COLGROUP_MOVING
+ && moving_object->get_group() != COLGROUP_MOVING_STATIC)
+ || !moving_object->is_valid())
+ continue;
+
+ for(MovingObjects::iterator i2 = moving_objects.begin();
+ i2 != moving_objects.end(); ++i2) {
+ MovingObject* moving_object_2 = *i2;
+ if(moving_object_2->get_group() != COLGROUP_TOUCHABLE
+ || !moving_object_2->is_valid())
+ continue;
+
+ if(intersects(moving_object->dest, moving_object_2->dest)) {
+ Vector normal;
+ CollisionHit hit;
+ get_hit_normal(moving_object->dest, moving_object_2->dest,
+ hit, normal);
+ if(!moving_object->collides(*moving_object_2, hit))
+ continue;
+ if(!moving_object_2->collides(*moving_object, hit))
+ continue;
+
+ moving_object->collision(*moving_object_2, hit);
+ moving_object_2->collision(*moving_object, hit);
+ }
+ }
+ }
+
+ // part3: COLGROUP_MOVING vs COLGROUP_MOVING
+ for(MovingObjects::iterator i = moving_objects.begin();
+ i != moving_objects.end(); ++i) {
+ MovingObject* moving_object = *i;
+
+ if((moving_object->get_group() != COLGROUP_MOVING
+ && moving_object->get_group() != COLGROUP_MOVING_STATIC)
+ || !moving_object->is_valid())
+ continue;
+
+ for(MovingObjects::iterator i2 = i+1;
+ i2 != moving_objects.end(); ++i2) {
+ MovingObject* moving_object_2 = *i2;
+ if((moving_object_2->get_group() != COLGROUP_MOVING
+ && moving_object_2->get_group() != COLGROUP_MOVING_STATIC)
+ || !moving_object_2->is_valid())
+ continue;
+
+ collision_object(moving_object, moving_object_2);
+ }
+ }
+
+ // apply object movement
+ for(MovingObjects::iterator i = moving_objects.begin();
+ i != moving_objects.end(); ++i) {
+ MovingObject* moving_object = *i;
+
+ moving_object->bbox = moving_object->dest;
+ moving_object->movement = Vector(0, 0);
+ }
+}
+
+bool
+Sector::is_free_of_tiles(const Rect& rect, const bool ignoreUnisolid) const
+{
+ using namespace collision;
+
+ for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
+ TileMap* solids = *i;
+
+ // test with all tiles in this rectangle
+ int starttilex = int(rect.p1.x - solids->get_x_offset()) / 32;
+ int starttiley = int(rect.p1.y - solids->get_y_offset()) / 32;
+ int max_x = int(rect.p2.x - solids->get_x_offset());
+ int max_y = int(rect.p2.y - solids->get_y_offset());
+
+ for(int x = starttilex; x*32 <= max_x; ++x) {
+ for(int y = starttiley; y*32 <= max_y; ++y) {
+ const Tile* tile = solids->get_tile(x, y);
+ if(!tile) continue;
+ if(tile->getAttributes() & Tile::SLOPE) {
+ AATriangle triangle;
+ Vector p1(x*32 + solids->get_x_offset(), y*32 + solids->get_y_offset());
+ Vector p2((x+1)*32 + solids->get_x_offset(), (y+1)*32 + solids->get_y_offset());
+ triangle = AATriangle(p1, p2, tile->getData());
+ Constraints constraints;
+ if(collision::rectangle_aatriangle(&constraints, rect, triangle) && (!ignoreUnisolid || !(tile->getAttributes() & Tile::UNISOLID))) return false;
+ }
+ if((tile->getAttributes() & Tile::SOLID) && (!ignoreUnisolid || !(tile->getAttributes() & Tile::UNISOLID))) return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+bool
+Sector::is_free_of_statics(const Rect& rect, const MovingObject* ignore_object, const bool ignoreUnisolid) const
+{
+ using namespace collision;
+
+ if (!is_free_of_tiles(rect, ignoreUnisolid)) return false;
+
+ for(MovingObjects::const_iterator i = moving_objects.begin();
+ i != moving_objects.end(); ++i) {
+ const MovingObject* moving_object = *i;
+ if (moving_object == ignore_object) continue;
+ if (!moving_object->is_valid()) continue;
+ if (moving_object->get_group() == COLGROUP_STATIC) {
+ if(intersects(rect, moving_object->get_bbox())) return false;
+ }
+ }
+
+ return true;
+}
+
+bool
+Sector::is_free_of_movingstatics(const Rect& rect, const MovingObject* ignore_object) const
+{
+ using namespace collision;
+
+ if (!is_free_of_tiles(rect)) return false;
+
+ for(MovingObjects::const_iterator i = moving_objects.begin();
+ i != moving_objects.end(); ++i) {
+ const MovingObject* moving_object = *i;
+ if (moving_object == ignore_object) continue;
+ if (!moving_object->is_valid()) continue;
+ if ((moving_object->get_group() == COLGROUP_MOVING)
+ || (moving_object->get_group() == COLGROUP_MOVING_STATIC)
+ || (moving_object->get_group() == COLGROUP_STATIC)) {
+ if(intersects(rect, moving_object->get_bbox())) return false;
+ }
+ }
+
+ return true;
+}
+
+bool
+Sector::add_bullet(const Vector& pos, float xm, Direction dir)
+{
+ // TODO remove this function and move these checks elsewhere...
+
+ Bullet* new_bullet = 0;
+ if((player_status->bonus == FIRE_BONUS &&
+ (int)bullets.size() >= player_status->max_fire_bullets) ||
+ (player_status->bonus == ICE_BONUS &&
+ (int)bullets.size() >= player_status->max_ice_bullets))
+ return false;
+ new_bullet = new Bullet(pos, xm, dir, player_status->bonus);
+ add_object(new_bullet);
+
+ sound_manager->play("sounds/shoot.wav");
+
+ return true;
+}
+
+bool
+Sector::add_smoke_cloud(const Vector& pos)
+{
+ add_object(new SmokeCloud(pos));
+ return true;
+}
+
+void
+Sector::play_music(MusicType type)
+{
+ currentmusic = type;
+ switch(currentmusic) {
+ case LEVEL_MUSIC:
+ sound_manager->play_music(music);
+ break;
+ case HERRING_MUSIC:
+ sound_manager->play_music("music/invincible.music");
+ break;
+ case HERRING_WARNING_MUSIC:
+ sound_manager->stop_music(TUX_INVINCIBLE_TIME_WARNING);
+ break;
+ default:
+ sound_manager->play_music("");
+ break;
+ }
+}
+
+MusicType
+Sector::get_music_type()
+{
+ return currentmusic;
+}
+
+int
+Sector::get_total_badguys()
+{
+ int total_badguys = 0;
+ for(GameObjects::iterator i = gameobjects.begin();
+ i != gameobjects.end(); ++i) {
+ BadGuy* badguy = dynamic_cast<BadGuy*> (*i);
+ if (badguy && badguy->countMe)
+ total_badguys++;
+ }
+
+ return total_badguys;
+}
+
+bool
+Sector::inside(const Rect& rect) const
+{
+ for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
+ TileMap* solids = *i;
+ bool horizontally = ((rect.p2.x >= 0 + solids->get_x_offset()) && (rect.p1.x <= solids->get_width() * 32 + solids->get_x_offset()));
+ bool vertically = (rect.p1.y <= solids->get_height() * 32 + solids->get_y_offset());
+
+ if (horizontally && vertically)
+ return true;
+ }
+ return false;
+}
+
+float
+Sector::get_width() const
+{
+ float width = 0;
+ for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin();
+ i != solid_tilemaps.end(); i++) {
+ TileMap* solids = *i;
+ if ((solids->get_width() * 32 + solids->get_x_offset()) > width) {
+ width = solids->get_width() * 32 + solids->get_x_offset();
+ }
+ }
+
+ return width;
+}
+
+float
+Sector::get_height() const
+{
+ float height = 0;
+ for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin();
+ i != solid_tilemaps.end(); i++) {
+ TileMap* solids = *i;
+ if ((solids->get_height() * 32 + solids->get_y_offset()) > height) {
+ height = solids->get_height() * 32 + solids->get_y_offset();
+ }
+ }
+
+ return height;
+}
+
+void
+Sector::change_solid_tiles(uint32_t old_tile_id, uint32_t new_tile_id)
+{
+ for(std::list<TileMap*>::const_iterator i = solid_tilemaps.begin(); i != solid_tilemaps.end(); i++) {
+ TileMap* solids = *i;
+ solids->change_all(old_tile_id, new_tile_id);
+ }
+}
+
+void
+Sector::set_ambient_light(float red, float green, float blue)
+{
+ ambient_light.red = red;
+ ambient_light.green = green;
+ ambient_light.blue = blue;
+}
+
+float
+Sector::get_ambient_red()
+{
+ return ambient_light.red;
+}
+
+float
+Sector::get_ambient_green()
+{
+ return ambient_light.green;
+}
+
+float
+Sector::get_ambient_blue()
+{
+ return ambient_light.blue;
+}
+
+void
+Sector::set_gravity(float gravity)
+{
+ log_warning << "Changing a Sector's gravitational constant might have unforeseen side-effects" << std::endl;
+ this->gravity = gravity;
+}
+
+float
+Sector::get_gravity() const
+{
+ return gravity;
+}
+
+/* EOF */
--- /dev/null
+// SuperTux - A Jump'n Run
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_SUPERTUX_SECTOR_HPP
+#define HEADER_SUPERTUX_SUPERTUX_SECTOR_HPP
+
+#include <list>
+#include <squirrel.h>
+#include <stdint.h>
+
+#include "scripting/ssector.hpp"
+#include "supertux/direction.hpp"
+#include "util/reader_fwd.hpp"
+#include "util/writer_fwd.hpp"
+#include "util/currenton.hpp"
+#include "video/color.hpp"
+
+namespace collision {
+class Constraints;
+}
+
+class Vector;
+class Rect;
+class Sprite;
+class GameObject;
+class Player;
+class Camera;
+class TileMap;
+class Bullet;
+class ScriptInterpreter;
+class SpawnPoint;
+class MovingObject;
+class CollisionHit;
+class Level;
+class Portable;
+class DrawingContext;
+class DisplayEffect;
+
+enum MusicType {
+ LEVEL_MUSIC,
+ HERRING_MUSIC,
+ HERRING_WARNING_MUSIC
+};
+
+/**
+ * Represents one of (potentially) multiple, separate parts of a Level.
+ *
+ * Sectors contain GameObjects, e.g. Badguys and Players.
+ */
+class Sector : public Scripting::SSector,
+ public Currenton<Sector>
+{
+public:
+ Sector(Level* parent);
+ ~Sector();
+
+ /// get parent level
+ Level* get_level();
+
+ /// read sector from lisp file
+ void parse(const Reader& lisp);
+ void parse_old_format(const Reader& lisp);
+
+ /// activates this sector (change music, initialize player class, ...)
+ void activate(const std::string& spawnpoint);
+ void activate(const Vector& player_pos);
+ void deactivate();
+
+ void update(float elapsed_time);
+ void update_game_objects();
+
+ void draw(DrawingContext& context);
+
+ /**
+ * runs a script in the context of the sector (sector_table will be the
+ * roottable of this squirrel VM)
+ */
+ HSQUIRRELVM run_script(std::istream& in, const std::string& sourcename);
+
+ /// adds a gameobject
+ void add_object(GameObject* object);
+
+ void set_name(const std::string& name)
+ { this->name = name; }
+ const std::string& get_name() const
+ { return name; }
+
+ /**
+ * tests if a given rectangle is inside the sector
+ * (a rectangle that is on top of the sector is considered inside)
+ */
+ bool inside(const Rect& rectangle) const;
+
+ void play_music(MusicType musictype);
+ MusicType get_music_type();
+
+ bool add_bullet(const Vector& pos, float xm, Direction dir);
+ bool add_smoke_cloud(const Vector& pos);
+
+ /** get currently activated sector. */
+ static Sector* current()
+ { return _current; }
+
+ /** Get total number of badguys */
+ int get_total_badguys();
+
+ /** Get total number of GameObjects of given type */
+ template<class T> int get_total_count()
+ {
+ int total = 0;
+ for(GameObjects::iterator i = gameobjects.begin(); i != gameobjects.end(); ++i) {
+ if (dynamic_cast<T*>(*i)) total++;
+ }
+ return total;
+ }
+
+ void collision_tilemap(collision::Constraints* constraints,
+ const Vector& movement, const Rect& dest) const;
+
+ /**
+ * Checks if the specified rectangle is free of (solid) tiles.
+ * Note that this does not include static objects, e.g. bonus blocks.
+ */
+ bool is_free_of_tiles(const Rect& rect, const bool ignoreUnisolid = false) const;
+ /**
+ * Checks if the specified rectangle is free of both
+ * 1.) solid tiles and
+ * 2.) MovingObjects in COLGROUP_STATIC.
+ * Note that this does not include badguys or players.
+ */
+ bool is_free_of_statics(const Rect& rect, const MovingObject* ignore_object = 0, const bool ignoreUnisolid = false) const;
+ /**
+ * Checks if the specified rectangle is free of both
+ * 1.) solid tiles and
+ * 2.) MovingObjects in COLGROUP_STATIC, COLGROUP_MOVINGSTATIC or COLGROUP_MOVING.
+ * This includes badguys and players.
+ */
+ bool is_free_of_movingstatics(const Rect& rect, const MovingObject* ignore_object = 0) const;
+
+ /**
+ * returns a list of players currently in the sector
+ */
+ std::vector<Player*> get_players() {
+ return std::vector<Player*>(1, this->player);
+ }
+
+ Rect get_active_region();
+
+ /**
+ * returns the width (in px) of a sector)
+ */
+ float get_width() const;
+
+ /**
+ * returns the height (in px) of a sector)
+ */
+ float get_height() const;
+
+ /**
+ * globally changes solid tilemaps' tile ids
+ */
+ void change_solid_tiles(uint32_t old_tile_id, uint32_t new_tile_id);
+
+ typedef std::vector<GameObject*> GameObjects;
+ typedef std::vector<MovingObject*> MovingObjects;
+ typedef std::vector<SpawnPoint*> SpawnPoints;
+ typedef std::vector<Portable*> Portables;
+
+ // --- Scripting ---
+ /**
+ * get/set color of ambient light
+ */
+ void set_ambient_light(float red, float green, float blue);
+ float get_ambient_red();
+ float get_ambient_green();
+ float get_ambient_blue();
+
+ /**
+ * set gravity throughout sector
+ */
+ void set_gravity(float gravity);
+ float get_gravity() const;
+
+private:
+ Level* level; /**< Parent level containing this sector */
+ uint32_t collision_tile_attributes(const Rect& dest) const;
+
+ void before_object_remove(GameObject* object);
+ bool before_object_add(GameObject* object);
+
+ void try_expose(GameObject* object);
+ void try_unexpose(GameObject* object);
+ void try_expose_me();
+ void try_unexpose_me();
+
+ /** Checks for all possible collisions. And calls the
+ collision_handlers, which the collision_objects provide for this
+ case (or not). */
+ void handle_collisions();
+
+ /**
+ * Does collision detection between 2 objects and does instant
+ * collision response handling in case of a collision
+ */
+ void collision_object(MovingObject* object1, MovingObject* object2) const;
+
+ /**
+ * Does collision detection of an object against all other static
+ * objects (and the tilemap) in the level. Collision response is done
+ * for the first hit in time. (other hits get ignored, the function
+ * should be called repeatedly to resolve those)
+ *
+ * returns true if the collision detection should be aborted for this object
+ * (because of ABORT_MOVE in the collision response or no collisions)
+ */
+ void collision_static(collision::Constraints* constraints,
+ const Vector& movement, const Rect& dest, GameObject& object);
+
+ void collision_static_constrains(MovingObject& object);
+
+ GameObject* parse_object(const std::string& name, const Reader& lisp);
+
+ void fix_old_tiles();
+
+ static Sector* _current;
+
+ std::string name;
+
+ std::vector<Bullet*> bullets;
+
+ std::string init_script;
+
+ /// container for newly created objects, they'll be added in Sector::update
+ GameObjects gameobjects_new;
+
+ MusicType currentmusic;
+
+ HSQOBJECT sector_table;
+ /// sector scripts
+ typedef std::vector<HSQOBJECT> ScriptList;
+ ScriptList scripts;
+
+ Color ambient_light;
+
+public: // TODO make this private again
+ /// show collision rectangles of moving objects (for debugging)
+ static bool show_collrects;
+ static bool draw_solids_only;
+
+ GameObjects gameobjects;
+ MovingObjects moving_objects;
+ SpawnPoints spawnpoints;
+ Portables portables;
+
+ std::string music;
+ float gravity;
+
+ // some special objects, where we need direct access
+ // (try to avoid accessing them directly)
+ Player* player;
+ std::list<TileMap*> solid_tilemaps;
+ Camera* camera;
+ DisplayEffect* effect;
+
+private:
+ Sector(const Sector&);
+ Sector& operator=(const Sector&);
+};
+
+#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include "supertux/main.hpp"
+#include "supertux/shrinkfade.hpp"
+#include "video/drawing_context.hpp"
+
+ShrinkFade::ShrinkFade(const Vector& dest, float fade_time)
+ : dest(dest), fade_time(fade_time), accum_time(0)
+{
+ speedleft = dest.x / fade_time;
+ speedright = (SCREEN_WIDTH - dest.x) / fade_time;
+ speedtop = dest.y / fade_time;
+ speedbottom = (SCREEN_HEIGHT - dest.y) / fade_time;
+}
+
+ShrinkFade::~ShrinkFade()
+{
+}
+
+void
+ShrinkFade::update(float elapsed_time)
+{
+ accum_time += elapsed_time;
+ if(accum_time > fade_time)
+ accum_time = fade_time;
+}
+
+void
+ShrinkFade::draw(DrawingContext& context)
+{
+ float progress = accum_time / fade_time;
+ context.draw_inverse_ellipse(dest,
+ Vector(2*SCREEN_WIDTH * (1.0f - progress),
+ 2*SCREEN_HEIGHT * (1.0f - progress)),
+ Color(0, 0, 0), LAYER_GUI+1);
+}
+
+bool
+ShrinkFade::done()
+{
+ return accum_time >= fade_time;
+}
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_SUPERTUX_SHRINKFADE_HPP
+#define HEADER_SUPERTUX_SUPERTUX_SHRINKFADE_HPP
+
+#include "math/vector.hpp"
+#include "supertux/screen_fade.hpp"
+
+/**
+ * Shrinks a rectangle screen towards a specific position
+ */
+class ShrinkFade : public ScreenFade
+{
+public:
+ ShrinkFade(const Vector& point, float fade_time);
+ virtual ~ShrinkFade();
+
+ virtual void update(float elapsed_time);
+ virtual void draw(DrawingContext& context);
+
+ virtual bool done();
+
+private:
+ Vector dest;
+ float fade_time;
+ float accum_time;
+ float speedleft, speedright, speedtop, speedbottom;
+};
+
+#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include <stdexcept>
+
+#include "lisp/list_iterator.hpp"
+#include "supertux/spawn_point.hpp"
+#include "util/log.hpp"
+
+SpawnPoint::SpawnPoint()
+{}
+
+SpawnPoint::SpawnPoint(const SpawnPoint& other)
+ : name(other.name), pos(other.pos)
+{}
+
+SpawnPoint::SpawnPoint(const lisp::Lisp* slisp)
+{
+ pos.x = -1;
+ pos.y = -1;
+ lisp::ListIterator iter(slisp);
+ while(iter.next()) {
+ const std::string& token = iter.item();
+ if(token == "name") {
+ iter.value()->get(name);
+ } else if(token == "x") {
+ iter.value()->get(pos.x);
+ } else if(token == "y") {
+ iter.value()->get(pos.y);
+ } else {
+ log_warning << "unknown token '" << token << "' in SpawnPoint" << std::endl;
+ }
+ }
+
+ if(name == "")
+ throw std::runtime_error("No name specified for spawnpoint");
+ if(pos.x < 0 || pos.y < 0)
+ throw std::runtime_error("Invalid coordinates for spawnpoint");
+}
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_SUPERTUX_SPAWN_POINT_HPP
+#define HEADER_SUPERTUX_SUPERTUX_SPAWN_POINT_HPP
+
+#include "math/vector.hpp"
+namespace lisp { class Lisp; }
+
+class SpawnPoint
+{
+public:
+ SpawnPoint();
+ SpawnPoint(const SpawnPoint& other);
+ SpawnPoint(const lisp::Lisp* lisp);
+
+ std::string name;
+ Vector pos;
+};
+
+#endif
+
+/* EOF */
--- /dev/null
+// SuperTux (Statistics module)
+// Copyright (C) 2004 Ricardo Cruz <rick2@aeiou.pt>
+// Copyright (C) 2006 Ondrej Hosek <ondra.hosek@gmail.com>
+// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include "supertux/statistics.hpp"
+
+#include <iomanip>
+#include <limits>
+
+#include "scripting/squirrel_util.hpp"
+#include "supertux/main.hpp"
+#include "supertux/resources.hpp"
+#include "util/gettext.hpp"
+#include "video/drawing_context.hpp"
+
+namespace {
+const int nv_coins = std::numeric_limits<int>::min();
+const int nv_badguys = std::numeric_limits<int>::min();
+const float nv_time = std::numeric_limits<float>::max();
+const int nv_secrets = std::numeric_limits<int>::min();
+}
+
+float WMAP_INFO_LEFT_X;
+float WMAP_INFO_RIGHT_X;
+float WMAP_INFO_TOP_Y1;
+float WMAP_INFO_TOP_Y2;
+
+Statistics::Statistics() :
+ coins(nv_coins),
+ total_coins(nv_coins),
+ badguys(nv_badguys),
+ total_badguys(nv_badguys),
+ time(nv_time),
+ secrets(nv_secrets),
+ total_secrets(nv_secrets),
+ valid(true)
+{
+ WMAP_INFO_LEFT_X = (SCREEN_WIDTH/2 + 80) + 32;
+ WMAP_INFO_RIGHT_X = SCREEN_WIDTH/2 + 368;
+ WMAP_INFO_TOP_Y1 = SCREEN_HEIGHT/2 + 172 - 16;
+ WMAP_INFO_TOP_Y2 = SCREEN_HEIGHT/2 + 172;
+}
+
+Statistics::~Statistics()
+{
+}
+
+/*
+ void
+ Statistics::parse(const Reader& reader)
+ {
+ reader.get("coins-collected", coins);
+ reader.get("coins-collected-total", total_coins);
+ reader.get("badguys-killed", badguys);
+ reader.get("badguys-killed-total", total_badguys);
+ reader.get("time-needed", time);
+ reader.get("secrets-found", secrets);
+ reader.get("secrets-found-total", total_secrets);
+ }
+
+ void
+ Statistics::write(lisp::Writer& writer)
+ {
+ writer.write("coins-collected", coins);
+ writer.write("coins-collected-total", total_coins);
+ writer.write("badguys-killed", badguys);
+ writer.write("badguys-killed-total", total_badguys);
+ writer.write("time-needed", time);
+ writer.write("secrets-found", secrets);
+ writer.write("secrets-found-total", total_secrets);
+ }
+*/
+
+void
+Statistics::serialize_to_squirrel(HSQUIRRELVM vm)
+{
+ // TODO: there's some bug in the unserialization routines that breaks stuff when an empty statistics table is written, so -- as a workaround -- let's make sure we will actually write something first
+ if (!((coins != nv_coins) || (total_coins != nv_coins) || (badguys != nv_badguys) || (total_badguys != nv_badguys) || (time != nv_time) || (secrets != nv_secrets) || (total_secrets != nv_secrets))) return;
+
+ sq_pushstring(vm, "statistics", -1);
+ sq_newtable(vm);
+ if (coins != nv_coins) Scripting::store_int(vm, "coins-collected", coins);
+ if (total_coins != nv_coins) Scripting::store_int(vm, "coins-collected-total", total_coins);
+ if (badguys != nv_badguys) Scripting::store_int(vm, "badguys-killed", badguys);
+ if (total_badguys != nv_badguys) Scripting::store_int(vm, "badguys-killed-total", total_badguys);
+ if (time != nv_time) Scripting::store_float(vm, "time-needed", time);
+ if (secrets != nv_secrets) Scripting::store_int(vm, "secrets-found", secrets);
+ if (total_secrets != nv_secrets) Scripting::store_int(vm, "secrets-found-total", total_secrets);
+ sq_createslot(vm, -3);
+}
+
+void
+Statistics::unserialize_from_squirrel(HSQUIRRELVM vm)
+{
+ sq_pushstring(vm, "statistics", -1);
+ if(SQ_FAILED(sq_get(vm, -2))) {
+ return;
+ }
+ Scripting::get_int(vm, "coins-collected", coins);
+ Scripting::get_int(vm, "coins-collected-total", total_coins);
+ Scripting::get_int(vm, "badguys-killed", badguys);
+ Scripting::get_int(vm, "badguys-killed-total", total_badguys);
+ Scripting::get_float(vm, "time-needed", time);
+ Scripting::get_int(vm, "secrets-found", secrets);
+ Scripting::get_int(vm, "secrets-found-total", total_secrets);
+ sq_pop(vm, 1);
+}
+
+void
+Statistics::draw_worldmap_info(DrawingContext& context)
+{
+ // skip draw if level was never played
+ if (coins == nv_coins) return;
+
+ // skip draw if stats were declared invalid
+ if (!valid) return;
+
+ context.draw_text(small_font, std::string("- ") + _("Best Level Statistics") + " -", Vector((WMAP_INFO_LEFT_X + WMAP_INFO_RIGHT_X) / 2, WMAP_INFO_TOP_Y1), ALIGN_CENTER, LAYER_GUI,Statistics::header_color);
+
+ std::string caption_buf;
+ std::string stat_buf;
+ float posy = WMAP_INFO_TOP_Y2;
+ for (int stat_no = 0; stat_no < 4; stat_no++) {
+ switch (stat_no)
+ {
+ case 0:
+ caption_buf = _("Max coins collected:");
+ stat_buf = coins_to_string(coins, total_coins);
+ break;
+ case 1:
+ caption_buf = _("Max fragging:");
+ stat_buf = frags_to_string(badguys, total_badguys);
+ break;
+ case 2:
+ caption_buf = _("Min time needed:");
+ stat_buf = time_to_string(time);
+ break;
+ case 3:
+ caption_buf = _("Max secrets found:");
+ stat_buf = secrets_to_string(secrets, total_secrets);
+ break;
+ default:
+ log_debug << "Invalid stat requested to be drawn" << std::endl;
+ break;
+ }
+
+ context.draw_text(small_font, caption_buf, Vector(WMAP_INFO_LEFT_X, posy), ALIGN_LEFT, LAYER_GUI, Statistics::header_color);
+ context.draw_text(small_font, stat_buf, Vector(WMAP_INFO_RIGHT_X, posy), ALIGN_RIGHT, LAYER_GUI, Statistics::header_color);
+ posy += small_font->get_height() + 2;
+ }
+
+}
+
+void
+Statistics::draw_endseq_panel(DrawingContext& context, Statistics* best_stats, Surface* backdrop)
+{
+ // skip draw if level was never played
+ // TODO: do we need this?
+ if (coins == nv_coins) return;
+
+ // skip draw if stats were declared invalid
+ if (!valid) return;
+
+ // abort if we have no backdrop
+ if (!backdrop) return;
+
+ int box_w = 220+110+110;
+ int box_h = 30+20+20+20;
+ int box_x = (int)((SCREEN_WIDTH - box_w) / 2);
+ int box_y = (int)(SCREEN_HEIGHT / 2) - box_h;
+
+ int bd_w = (int)backdrop->get_width();
+ int bd_h = (int)backdrop->get_height();
+ int bd_x = (int)((SCREEN_WIDTH - bd_w) / 2);
+ int bd_y = box_y + (box_h / 2) - (bd_h / 2);
+
+ int col1_x = box_x;
+ int col2_x = col1_x+200;
+ int col3_x = col2_x+130;
+
+ int row1_y = box_y;
+ int row2_y = row1_y+30;
+ int row3_y = row2_y+20;
+ int row4_y = row3_y+20;
+
+ context.push_transform();
+ context.set_alpha(0.5);
+ context.draw_surface(backdrop, Vector(bd_x, bd_y), LAYER_GUI);
+ context.pop_transform();
+
+ context.draw_text(normal_font, _("You"), Vector(col2_x, row1_y), ALIGN_LEFT, LAYER_GUI, Statistics::header_color);
+ context.draw_text(normal_font, _("Best"), Vector(col3_x, row1_y), ALIGN_LEFT, LAYER_GUI, Statistics::header_color);
+
+ context.draw_text(normal_font, _("Coins"), Vector(col2_x-16, row3_y), ALIGN_RIGHT, LAYER_GUI, Statistics::header_color);
+ int coins_best = (best_stats && (best_stats->coins > coins)) ? best_stats->coins : coins;
+ int total_coins_best = (best_stats && (best_stats->total_coins > total_coins)) ? best_stats->total_coins : total_coins;
+ context.draw_text(normal_font, coins_to_string(coins, total_coins), Vector(col2_x, row3_y), ALIGN_LEFT, LAYER_GUI, Statistics::text_color);
+ context.draw_text(normal_font, coins_to_string(coins_best, total_coins_best), Vector(col3_x, row3_y), ALIGN_LEFT, LAYER_GUI, Statistics::text_color);
+
+ context.draw_text(normal_font, _("Secrets"), Vector(col2_x-16, row4_y), ALIGN_RIGHT, LAYER_GUI, Statistics::header_color);
+ int secrets_best = (best_stats && (best_stats->secrets > secrets)) ? best_stats->secrets : secrets;
+ int total_secrets_best = (best_stats && (best_stats->total_secrets > total_secrets)) ? best_stats->total_secrets : total_secrets;
+ context.draw_text(normal_font, secrets_to_string(secrets, total_secrets), Vector(col2_x, row4_y), ALIGN_LEFT, LAYER_GUI, Statistics::text_color);
+ context.draw_text(normal_font, secrets_to_string(secrets_best, total_secrets_best), Vector(col3_x, row4_y), ALIGN_LEFT, LAYER_GUI, Statistics::text_color);
+
+ context.draw_text(normal_font, _("Time"), Vector(col2_x-16, row2_y), ALIGN_RIGHT, LAYER_GUI, Statistics::header_color);
+ float time_best = (best_stats && (best_stats->time < time)) ? best_stats->time : time;
+ context.draw_text(normal_font, time_to_string(time), Vector(col2_x, row2_y), ALIGN_LEFT, LAYER_GUI, Statistics::text_color);
+ context.draw_text(normal_font, time_to_string(time_best), Vector(col3_x, row2_y), ALIGN_LEFT, LAYER_GUI, Statistics::text_color);
+}
+
+void
+Statistics::zero()
+{
+ reset();
+ total_coins = 0;
+ total_badguys = 0;
+ total_secrets = 0;
+}
+
+void
+Statistics::reset()
+{
+ coins = 0;
+ badguys = 0;
+ time = 0;
+ secrets = 0;
+}
+
+void
+Statistics::merge(const Statistics& s2)
+{
+ if (!s2.valid) return;
+ coins = std::max(coins, s2.coins);
+ total_coins = s2.total_coins;
+ badguys = std::max(badguys, s2.badguys);
+ total_badguys = s2.total_badguys;
+ time = std::min(time, s2.time);
+ secrets = std::max(secrets, s2.secrets);
+ total_secrets = s2.total_secrets;
+}
+
+void
+Statistics::operator+=(const Statistics& s2)
+{
+ if (!s2.valid) return;
+ if (s2.coins != nv_coins) coins += s2.coins;
+ if (s2.total_coins != nv_coins) total_coins += s2.total_coins;
+ if (s2.badguys != nv_badguys) badguys += s2.badguys;
+ if (s2.total_badguys != nv_badguys) total_badguys += s2.total_badguys;
+ if (s2.time != nv_time) time += s2.time;
+ if (s2.secrets != nv_secrets) secrets += s2.secrets;
+ if (s2.total_secrets != nv_secrets) total_secrets += s2.total_secrets;
+}
+
+void
+Statistics::declare_invalid()
+{
+ valid = false;
+}
+
+std::string
+Statistics::coins_to_string(int coins, int total_coins) {
+ std::ostringstream os;
+ os << std::min(coins, 999) << "/" << std::min(total_coins, 999);
+ return os.str();
+}
+
+std::string
+Statistics::frags_to_string(int badguys, int total_badguys) {
+ std::ostringstream os;
+ os << std::min(badguys, 999) << "/" << std::min(total_badguys, 999);
+ return os.str();
+}
+
+std::string
+Statistics::time_to_string(float time) {
+ int time_csecs = std::min(static_cast<int>(time * 100), 99 * 6000 + 9999);
+ int mins = (time_csecs / 6000);
+ int secs = (time_csecs % 6000) / 100;
+ int cscs = (time_csecs % 6000) % 100;
+
+ std::ostringstream os;
+ os << std::setw(2) << std::setfill('0') << mins << ":" << std::setw(2) << std::setfill('0') << secs << "." << std::setw(2) << std::setfill('0') << cscs;
+ return os.str();
+}
+
+std::string
+Statistics::secrets_to_string(int secrets, int total_secrets) {
+ std::ostringstream os;
+ os << std::min(secrets, 999) << "/" << std::min(total_secrets, 999);
+ return os.str();
+}
+
+/* EOF */
--- /dev/null
+// SuperTux (Statistics module)
+// Copyright (C) 2004 Ricardo Cruz <rick2@aeiou.pt>
+// Copyright (C) 2006 Ondrej Hosek <ondra.hosek@gmail.com>
+// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_SUPERTUX_STATISTICS_HPP
+#define HEADER_SUPERTUX_SUPERTUX_STATISTICS_HPP
+
+#include <squirrel.h>
+
+#include "video/color.hpp"
+
+namespace lisp { class Writer; }
+namespace lisp { class Lisp; }
+class Surface;
+class DrawingContext;
+
+/** This class is a layer between level and worldmap to keep
+ * track of stuff like scores, and minor, but funny things, like
+ * number of jumps and stuff */
+class Statistics
+{
+ static Color header_color;
+ static Color text_color;
+public:
+ int coins; /**< coins collected */
+ int total_coins; /**< coins in level */
+ int badguys; /**< badguys actively killed */
+ int total_badguys; /**< (vincible) badguys in level */
+ float time; /**< seconds needed */
+ int secrets; /**< secret areas found */
+ int total_secrets; /**< secret areas in level */
+
+public:
+ Statistics(); /**< Creates new statistics, call reset() before counting */
+ ~Statistics();
+
+ /// read statistics from lisp file
+ //void parse(const Reader& lisp);
+ /// write statistics to lisp file
+ //void write(lisp::Writer& writer);
+
+ /**
+ * serialize statistics object as squirrel table "statistics"
+ */
+ void serialize_to_squirrel(HSQUIRRELVM vm);
+
+ /**
+ * unserialize statistics object from squirrel table "statistics"
+ */
+ void unserialize_from_squirrel(HSQUIRRELVM vm);
+
+ void draw_worldmap_info(DrawingContext& context); /**< draw worldmap stat HUD */
+ void draw_endseq_panel(DrawingContext& context, Statistics* best_stats, Surface* backdrop); /**< draw panel shown during level's end sequence */
+
+ void zero(); /**< Set stats to zero */
+ void reset(); /**< Set stats (but not totals) to zero */
+ void merge(const Statistics& stats); /**< Given another Statistics object finds the best of each one */
+ void operator+=(const Statistics& o); /**< Add two Statistics objects */
+
+ void declare_invalid(); /**< marks statistics as invalid for their entire lifetime (e.g. after cheating). Invalid statistics will not be merged or drawn. */
+
+ static std::string coins_to_string(int coins, int total_coins);
+ static std::string frags_to_string(int badguys, int total_badguys);
+ static std::string time_to_string(float time);
+ static std::string secrets_to_string(int secrets, int total_secrets);
+
+private:
+ bool valid; /**< stores whether these statistics can be trusted */
+
+};
+
+#endif /*SUPERTUX_STATISTICS_H*/
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include "supertux/textscroller.hpp"
+
+#include "audio/sound_manager.hpp"
+#include "control/joystickkeyboardcontroller.hpp"
+#include "lisp/lisp.hpp"
+#include "lisp/parser.hpp"
+#include "supertux/fadeout.hpp"
+#include "supertux/main.hpp"
+#include "supertux/mainloop.hpp"
+#include "supertux/resources.hpp"
+#include "video/drawing_context.hpp"
+
+static const float DEFAULT_SPEED = 20;
+static const float LEFT_BORDER = 50;
+static const float SCROLL = 60;
+static const float ITEMS_SPACE = 4;
+
+TextScroller::TextScroller(const std::string& filename)
+{
+ defaultspeed = DEFAULT_SPEED;
+ speed = defaultspeed;
+
+ std::string text;
+ std::string background_file;
+
+ lisp::Parser parser;
+ try {
+ const lisp::Lisp* root = parser.parse(filename);
+
+ const lisp::Lisp* text_lisp = root->get_lisp("supertux-text");
+ if(!text_lisp)
+ throw std::runtime_error("File isn't a supertux-text file");
+
+ if(!text_lisp->get("text", text))
+ throw std::runtime_error("file doesn't contain a text field");
+ if(!text_lisp->get("background", background_file))
+ throw std::runtime_error("file doesn't contain a background file");
+ text_lisp->get("speed", defaultspeed);
+ text_lisp->get("music", music);
+ } catch(std::exception& e) {
+ std::ostringstream msg;
+ msg << "Couldn't load file '" << filename << "': " << e.what() << std::endl;
+ throw std::runtime_error(msg.str());
+ }
+
+ // Split text string lines into a vector
+ lines = InfoBoxLine::split(text, SCREEN_WIDTH - 2*LEFT_BORDER);
+
+ // load background image
+ background.reset(new Surface("images/background/" + background_file));
+
+ scroll = 0;
+ fading = false;
+}
+
+TextScroller::~TextScroller()
+{
+ for(std::vector<InfoBoxLine*>::iterator i = lines.begin(); i != lines.end(); i++) delete *i;
+}
+
+void
+TextScroller::setup()
+{
+ sound_manager->play_music(music);
+}
+
+void
+TextScroller::update(float elapsed_time)
+{
+ if(g_main_controller->hold(Controller::UP)) {
+ speed = -defaultspeed*5;
+ } else if(g_main_controller->hold(Controller::DOWN)) {
+ speed = defaultspeed*5;
+ } else {
+ speed = defaultspeed;
+ }
+ if(g_main_controller->pressed(Controller::JUMP)
+ || g_main_controller->pressed(Controller::ACTION)
+ || g_main_controller->pressed(Controller::MENU_SELECT))
+ scroll += SCROLL;
+ if(g_main_controller->pressed(Controller::PAUSE_MENU)) {
+ g_main_loop->exit_screen(new FadeOut(0.5));
+ }
+
+ scroll += speed * elapsed_time;
+
+ if(scroll < 0)
+ scroll = 0;
+}
+
+void
+TextScroller::draw(DrawingContext& context)
+{
+ context.draw_filled_rect(Vector(0, 0), Vector(SCREEN_WIDTH, SCREEN_HEIGHT),
+ Color(0.6f, 0.7f, 0.8f, 0.5f), 0);
+ context.draw_surface(background.get(), Vector(SCREEN_WIDTH/2 - background->get_width()/2 , SCREEN_HEIGHT/2 - background->get_height()/2), 0);
+
+ float y = SCREEN_HEIGHT - scroll;
+ for(size_t i = 0; i < lines.size(); i++) {
+ if (y + lines[i]->get_height() >= 0 && SCREEN_HEIGHT - y >= 0) {
+ lines[i]->draw(context, Rect(LEFT_BORDER, y, SCREEN_WIDTH - 2*LEFT_BORDER, y), LAYER_GUI);
+ }
+
+ y += lines[i]->get_height();
+ }
+
+ if(y < 0 && !fading ) {
+ fading = true;
+ g_main_loop->exit_screen(new FadeOut(0.5));
+ }
+}
+
+InfoBox::InfoBox(const std::string& text)
+ : firstline(0)
+{
+ // Split text string lines into a vector
+ lines = InfoBoxLine::split(text, 400);
+
+ try
+ {
+ // get the arrow sprites
+ arrow_scrollup = new Surface("images/engine/menu/scroll-up.png");
+ arrow_scrolldown = new Surface("images/engine/menu/scroll-down.png");
+ }
+ catch (std::exception& e)
+ {
+ log_warning << "Could not load scrolling images: " << e.what() << std::endl;
+ arrow_scrollup = 0;
+ arrow_scrolldown = 0;
+ }
+}
+
+InfoBox::~InfoBox()
+{
+ for(std::vector<InfoBoxLine*>::iterator i = lines.begin();
+ i != lines.end(); i++)
+ delete *i;
+ delete arrow_scrollup;
+ delete arrow_scrolldown;
+}
+
+void
+InfoBox::draw(DrawingContext& context)
+{
+ float x1 = SCREEN_WIDTH/2-200;
+ float y1 = SCREEN_HEIGHT/2-200;
+ float width = 400;
+ float height = 200;
+
+ context.draw_filled_rect(Vector(x1, y1), Vector(width, height),
+ Color(0.6f, 0.7f, 0.8f, 0.5f), LAYER_GUI-1);
+
+ float y = y1;
+ bool linesLeft = false;
+ for(size_t i = firstline; i < lines.size(); ++i) {
+ if(y >= y1 + height) {
+ linesLeft = true;
+ break;
+ }
+
+ lines[i]->draw(context, Rect(x1, y, x1+width, y), LAYER_GUI);
+ y += lines[i]->get_height();
+ }
+
+ {
+ // draw the scrolling arrows
+ if (arrow_scrollup && firstline > 0)
+ context.draw_surface(arrow_scrollup,
+ Vector( x1 + width - arrow_scrollup->get_width(), // top-right corner of box
+ y1), LAYER_GUI);
+
+ if (arrow_scrolldown && linesLeft && firstline < lines.size()-1)
+ context.draw_surface(arrow_scrolldown,
+ Vector( x1 + width - arrow_scrolldown->get_width(), // bottom-light corner of box
+ y1 + height - arrow_scrolldown->get_height()),
+ LAYER_GUI);
+ }
+}
+
+void
+InfoBox::scrollup()
+{
+ if(firstline > 0)
+ firstline--;
+}
+
+void
+InfoBox::scrolldown()
+{
+ if(firstline < lines.size()-1)
+ firstline++;
+}
+
+void
+InfoBox::pageup()
+{
+}
+
+void
+InfoBox::pagedown()
+{
+}
+
+namespace {
+Font* get_font_by_format_char(char format_char) {
+ switch(format_char)
+ {
+ case ' ':
+ return small_font;
+ break;
+ case '-':
+ return big_font;
+ break;
+ case '\t':
+ case '*':
+ case '#':
+ case '!':
+ return normal_font;
+ break;
+ default:
+ return normal_font;
+ log_warning << "Unknown format_char: '" << format_char << "'" << std::endl;
+ break;
+ }
+}
+
+Color get_color_by_format_char(char format_char) {
+ switch(format_char)
+ {
+ case ' ':
+ return TextScroller::small_color;
+ break;
+ case '-':
+ return TextScroller::heading_color;
+ break;
+ case '*':
+ return TextScroller::reference_color;
+ case '\t':
+ case '#':
+ case '!':
+ return TextScroller::normal_color;
+ break;
+ default:
+ return Color(0,0,0);
+ log_warning << "Unknown format_char: '" << format_char << "'" << std::endl;
+ break;
+ }
+}
+
+InfoBoxLine::LineType get_linetype_by_format_char(char format_char) {
+ switch(format_char)
+ {
+ case ' ':
+ return InfoBoxLine::SMALL;
+ break;
+ case '\t':
+ return InfoBoxLine::NORMAL;
+ break;
+ case '-':
+ return InfoBoxLine::HEADING;
+ break;
+ case '*':
+ return InfoBoxLine::REFERENCE;
+ break;
+ case '#':
+ return InfoBoxLine::NORMAL_LEFT;
+ break;
+ case '!':
+ return InfoBoxLine::IMAGE;
+ break;
+ default:
+ return InfoBoxLine::SMALL;
+ log_warning << "Unknown format_char: '" << format_char << "'" << std::endl;
+ break;
+ }
+}
+}
+
+InfoBoxLine::InfoBoxLine(char format_char, const std::string& text) :
+ lineType(NORMAL),
+ font(normal_font),
+ text(text),
+ image(0)
+{
+ font = get_font_by_format_char(format_char);
+ lineType = get_linetype_by_format_char(format_char);
+ color = get_color_by_format_char(format_char);
+ if (lineType == IMAGE) image = new Surface(text);
+}
+
+InfoBoxLine::~InfoBoxLine()
+{
+ delete image;
+}
+
+const std::vector<InfoBoxLine*>
+InfoBoxLine::split(const std::string& text, float width)
+{
+ std::vector<InfoBoxLine*> lines;
+
+ std::string::size_type i = 0;
+ std::string::size_type l;
+ char format_char = '#';
+ while(i < text.size()) {
+ // take care of empty lines - represent them as blank lines of normal text
+ if (text[i] == '\n') {
+ lines.push_back(new InfoBoxLine('\t', ""));
+ i++;
+ continue;
+ }
+
+ // extract the format_char
+ format_char = text[i];
+ i++;
+ if (i >= text.size()) break;
+
+ // extract one line
+ l = text.find("\n", i);
+ if (l == std::string::npos) l=text.size();
+ std::string s = text.substr(i, l-i);
+ i = l+1;
+
+ // if we are dealing with an image, just store the line
+ if (format_char == '!') {
+ lines.push_back(new InfoBoxLine(format_char, s));
+ continue;
+ }
+
+ // append wrapped parts of line into list
+ std::string overflow;
+ do {
+ Font* font = get_font_by_format_char(format_char);
+ std::string s2 = s;
+ if (font) s2 = font->wrap_to_width(s2, width, &overflow);
+ lines.push_back(new InfoBoxLine(format_char, s2));
+ s = overflow;
+ } while (s.length() > 0);
+ }
+
+ return lines;
+}
+
+void
+InfoBoxLine::draw(DrawingContext& context, const Rect& bbox, int layer)
+{
+ Vector position = bbox.p1;
+ switch (lineType) {
+ case IMAGE:
+ context.draw_surface(image, Vector( (bbox.p1.x + bbox.p2.x - image->get_width()) / 2, position.y), layer);
+ break;
+ case NORMAL_LEFT:
+ context.draw_text(font, text, Vector(position.x, position.y), ALIGN_LEFT, layer, color);
+ break;
+ default:
+ context.draw_text(font, text, Vector((bbox.p1.x + bbox.p2.x) / 2, position.y), ALIGN_CENTER, layer, color);
+ break;
+ }
+}
+
+float
+InfoBoxLine::get_height()
+{
+ switch (lineType) {
+ case IMAGE:
+ return image->get_height() + ITEMS_SPACE;
+ case NORMAL_LEFT:
+ return font->get_height() + ITEMS_SPACE;
+ default:
+ return font->get_height() + ITEMS_SPACE;
+ }
+}
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_SUPERTUX_TEXTSCROLLER_HPP
+#define HEADER_SUPERTUX_SUPERTUX_TEXTSCROLLER_HPP
+
+#include <map>
+#include <memory>
+
+#include "supertux/screen.hpp"
+#include "video/color.hpp"
+
+class DrawingContext;
+class Surface;
+class Font;
+
+/**
+ * Helper class for InfoBox: Represents a line of text
+ */
+class InfoBoxLine
+{
+public:
+ enum LineType { NORMAL, NORMAL_LEFT, SMALL, HEADING, REFERENCE, IMAGE};
+
+ InfoBoxLine(char format_char, const std::string& text);
+ ~InfoBoxLine();
+
+ void draw(DrawingContext& context, const Rect& bbox, int layer);
+ float get_height();
+
+ static const std::vector<InfoBoxLine*> split(const std::string& text, float width);
+
+private:
+ InfoBoxLine::LineType lineType;
+ Font* font;
+ Color color;
+ std::string text;
+ Surface* image;
+};
+
+/** This class is displaying a box with information text inside the game
+ */
+class InfoBox
+{
+public:
+ InfoBox(const std::string& text);
+ ~InfoBox();
+
+ void draw(DrawingContext& context);
+ void scrolldown();
+ void scrollup();
+ void pagedown();
+ void pageup();
+
+private:
+ size_t firstline;
+ std::vector<InfoBoxLine*> lines;
+ std::map<std::string, Surface*> images;
+ Surface* arrow_scrollup;
+ Surface* arrow_scrolldown;
+};
+
+/**
+ * Screen that displays intro text, extro text, etc.
+ */
+class TextScroller : public Screen
+{
+public:
+ TextScroller(const std::string& file);
+ virtual ~TextScroller();
+
+ void setup();
+ void draw(DrawingContext& context);
+ void update(float elapsed_time);
+
+ static Color small_color;
+ static Color heading_color;
+ static Color reference_color;
+ static Color normal_color;
+private:
+ float defaultspeed;
+ float speed;
+ std::string music;
+ std::auto_ptr<Surface> background;
+ std::vector<InfoBoxLine*> lines;
+ float scroll;
+ bool fading;
+
+private:
+ TextScroller(const TextScroller&);
+ TextScroller& operator=(const TextScroller&);
+};
+
+#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include "supertux/tile.hpp"
+
+#include "lisp/lisp.hpp"
+#include "supertux/tile_set.hpp"
+#include "supertux/timer.hpp"
+#include "video/drawing_context.hpp"
+
+Tile::Tile(const TileSet *new_tileset) :
+ tileset(new_tileset),
+ attributes(0),
+ data(0),
+ anim_fps(1)
+{
+}
+
+Tile::Tile(const TileSet *new_tileset, std::vector<std::string> images, Rect rect,
+ uint32_t attributes, uint32_t data, float animfps) :
+ tileset(new_tileset),
+ attributes(attributes),
+ data(data),
+ anim_fps(animfps)
+{
+ for(std::vector<std::string>::iterator i = images.begin(); i != images.end(); ++i) {
+ imagespecs.push_back(ImageSpec(*i, rect));
+ }
+ correct_attributes();
+}
+
+Tile::~Tile()
+{
+ for(std::vector<Surface*>::iterator i = images.begin(); i != images.end();
+ ++i) {
+ delete *i;
+ }
+}
+
+uint32_t
+Tile::parse(const Reader& reader)
+{
+ uint32_t id;
+ if(!reader.get("id", id)) {
+ throw std::runtime_error("Missing tile-id.");
+ }
+
+ bool value = false;
+ if(reader.get("solid", value) && value)
+ attributes |= SOLID;
+ if(reader.get("unisolid", value) && value)
+ attributes |= UNISOLID | SOLID;
+ if(reader.get("brick", value) && value)
+ attributes |= BRICK;
+ if(reader.get("ice", value) && value)
+ attributes |= ICE;
+ if(reader.get("water", value) && value)
+ attributes |= WATER;
+ if(reader.get("hurts", value) && value)
+ attributes |= HURTS;
+ if(reader.get("fire", value) && value)
+ attributes |= FIRE;
+ if(reader.get("fullbox", value) && value)
+ attributes |= FULLBOX;
+ if(reader.get("coin", value) && value)
+ attributes |= COIN;
+ if(reader.get("goal", value) && value)
+ attributes |= GOAL;
+
+ if(reader.get("north", value) && value)
+ data |= WORLDMAP_NORTH;
+ if(reader.get("south", value) && value)
+ data |= WORLDMAP_SOUTH;
+ if(reader.get("west", value) && value)
+ data |= WORLDMAP_WEST;
+ if(reader.get("east", value) && value)
+ data |= WORLDMAP_EAST;
+ if(reader.get("stop", value) && value)
+ data |= WORLDMAP_STOP;
+
+ reader.get("data", data);
+ reader.get("anim-fps", anim_fps);
+
+ if(reader.get("slope-type", data)) {
+ attributes |= SOLID | SLOPE;
+ }
+
+ const lisp::Lisp* images;
+#ifdef DEBUG
+ images = reader.get_lisp("editor-images");
+ if(images)
+ parse_images(*images);
+ else {
+#endif /*DEBUG*/
+ images = reader.get_lisp("images");
+ if(images)
+ parse_images(*images);
+#ifdef DEBUG
+ }
+#endif /*DEBUG*/
+
+ correct_attributes();
+ return id;
+}
+
+void
+Tile::parse_images(const Reader& images_lisp)
+{
+ const lisp::Lisp* list = &images_lisp;
+ while(list) {
+ const lisp::Lisp* cur = list->get_car();
+ if(cur->get_type() == lisp::Lisp::TYPE_STRING) {
+ std::string file;
+ cur->get(file);
+ imagespecs.push_back(ImageSpec(file, Rect(0, 0, 0, 0)));
+ } else if(cur->get_type() == lisp::Lisp::TYPE_CONS &&
+ cur->get_car()->get_type() == lisp::Lisp::TYPE_SYMBOL &&
+ cur->get_car()->get_symbol() == "region") {
+ const lisp::Lisp* ptr = cur->get_cdr();
+
+ std::string file;
+ float x = 0, y = 0, w = 0, h = 0;
+ ptr->get_car()->get(file); ptr = ptr->get_cdr();
+ ptr->get_car()->get(x); ptr = ptr->get_cdr();
+ ptr->get_car()->get(y); ptr = ptr->get_cdr();
+ ptr->get_car()->get(w); ptr = ptr->get_cdr();
+ ptr->get_car()->get(h);
+ imagespecs.push_back(ImageSpec(file, Rect(x, y, x+w, y+h)));
+ } else {
+ log_warning << "Expected string or list in images tag" << std::endl;
+ continue;
+ }
+
+ list = list->get_cdr();
+ }
+}
+
+void
+Tile::load_images()
+{
+ const std::string& tiles_path = tileset->tiles_path;
+
+ assert(images.size() == 0);
+ for(std::vector<ImageSpec>::iterator i = imagespecs.begin(); i !=
+ imagespecs.end(); ++i) {
+ const ImageSpec& spec = *i;
+ Surface* surface;
+ std::string file = tiles_path + spec.file;
+ if(spec.rect.get_width() <= 0) {
+ surface = new Surface(file);
+ } else {
+ surface = new Surface(file,
+ (int) spec.rect.p1.x,
+ (int) spec.rect.p1.y,
+ (int) spec.rect.get_width(),
+ (int) spec.rect.get_height());
+ }
+ images.push_back(surface);
+ }
+}
+
+void
+Tile::draw(DrawingContext& context, const Vector& pos, int z_pos) const
+{
+ if(images.size() > 1) {
+ size_t frame = size_t(game_time * anim_fps) % images.size();
+ context.draw_surface(images[frame], pos, z_pos);
+ } else if (images.size() == 1) {
+ context.draw_surface(images[0], pos, z_pos);
+ }
+}
+
+void Tile::correct_attributes()
+{
+ //Fix little oddities in attributes (not many, currently...)
+ if(!(attributes & SOLID) && (attributes & SLOPE || attributes & UNISOLID)) {
+ attributes |= SOLID;
+ //But still be vocal about it
+ log_warning << "Tile with image " << imagespecs[0].file << " needs solid attribute." << std::endl;
+ }
+}
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_SUPERTUX_TILE_HPP
+#define HEADER_SUPERTUX_SUPERTUX_TILE_HPP
+
+#include <stdint.h>
+#include <vector>
+
+#include "math/rect.hpp"
+#include "video/surface.hpp"
+#include "util/reader_fwd.hpp"
+
+class TileSet;
+class DrawingContext;
+
+/**
+ Tile Class
+*/
+class Tile
+{
+public:
+ /// bitset for tile attributes
+ enum {
+ /** solid tile that is indestructible by Tux */
+ SOLID = 0x0001,
+ /** uni-directional solid tile */
+ UNISOLID = 0x0002,
+ /** a brick that can be destroyed by jumping under it */
+ BRICK = 0x0004,
+ /** the level should be finished when touching a goaltile.
+ * if data is 0 then the endsequence should be triggered, if data is 1
+ * then we can finish the level instantly.
+ */
+ GOAL = 0x0008,
+ /** slope tile */
+ SLOPE = 0x0010,
+ /** Bonusbox, content is stored in \a data */
+ FULLBOX = 0x0020,
+ /** Tile is a coin */
+ COIN = 0x0040,
+
+ /* interesting flags (the following are passed to gameobjects) */
+ FIRST_INTERESTING_FLAG = 0x0100,
+
+ /** an ice brick that makes tux sliding more than usual */
+ ICE = 0x0100,
+ /** a water tile in which tux starts to swim */
+ WATER = 0x0200,
+ /** a tile that hurts the player if he touches it */
+ HURTS = 0x0400,
+ /** for lava: WATER, HURTS, FIRE */
+ FIRE = 0x0800
+ };
+
+ /// worldmap flags
+ enum {
+ WORLDMAP_NORTH = 0x0001,
+ WORLDMAP_SOUTH = 0x0002,
+ WORLDMAP_EAST = 0x0004,
+ WORLDMAP_WEST = 0x0008,
+ WORLDMAP_DIR_MASK = 0x000f,
+
+ WORLDMAP_STOP = 0x0010,
+
+ // convenience values ("C" stands for crossroads)
+ WORLDMAP_CNSE = WORLDMAP_NORTH | WORLDMAP_SOUTH | WORLDMAP_EAST,
+ WORLDMAP_CNSW = WORLDMAP_NORTH | WORLDMAP_SOUTH | WORLDMAP_WEST,
+ WORLDMAP_CNEW = WORLDMAP_NORTH | WORLDMAP_EAST | WORLDMAP_WEST,
+ WORLDMAP_CSEW = WORLDMAP_SOUTH | WORLDMAP_EAST | WORLDMAP_WEST,
+ WORLDMAP_CNSEW = WORLDMAP_NORTH | WORLDMAP_SOUTH | WORLDMAP_EAST | WORLDMAP_WEST
+ };
+
+ struct ImageSpec {
+ ImageSpec(const std::string& newfile, const Rect& newrect)
+ : file(newfile), rect(newrect)
+ { }
+
+ std::string file;
+ Rect rect;
+ };
+
+private:
+ const TileSet *tileset;
+ std::vector<ImageSpec> imagespecs;
+ std::vector<Surface*> images;
+
+ /// tile attributes
+ uint32_t attributes;
+
+ /** General purpose data attached to a tile (content of a box, type of coin)*/
+ int data;
+
+ float anim_fps;
+
+public:
+ ~Tile();
+
+ /** Draw a tile on the screen */
+ void draw(DrawingContext& context, const Vector& pos, int z_pos) const;
+
+ uint32_t getAttributes() const
+ { return attributes; }
+
+ int getData() const
+ { return data; }
+
+ /// returns the width of the tile in pixels
+ int getWidth() const
+ {
+ if(!images.size())
+ return 0;
+ return (int) images[0]->get_width();
+ }
+
+ /// returns the height of the tiles in pixels
+ int getHeight() const
+ {
+ if(!images.size())
+ return 0;
+ return (int) images[0]->get_height();
+ }
+
+protected:
+ friend class TileSet;
+ Tile(const TileSet *tileset);
+ Tile(const TileSet *tileset, std::vector<std::string> images, Rect rect,
+ uint32_t attributes = 0, uint32_t data = 0, float animfps = 1.0);
+
+ void load_images();
+
+ /// parses the tile and returns it's id number
+ uint32_t parse(const Reader& reader);
+ void parse_images(const Reader& cur);
+
+ //Correct small oddities in attributes that naive people
+ //might miss (and rebuke them for it)
+ void correct_attributes();
+
+private:
+ Tile(const Tile&);
+ Tile& operator=(const Tile&);
+};
+
+#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include "supertux/tile_manager.hpp"
+
+#include <limits>
+#include <memory>
+
+#include "lisp/list_iterator.hpp"
+#include "supertux/tile_set.hpp"
+
+TileManager* tile_manager = NULL;
+TileSet* current_tileset = NULL;
+
+TileManager::TileManager()
+{
+}
+
+TileManager::~TileManager()
+{
+}
+
+TileSet* TileManager::get_tileset(const std::string &filename)
+{
+ TileSets::const_iterator i = tilesets.find(filename);
+ if(i != tilesets.end())
+ return i->second;
+
+ std::auto_ptr<TileSet> tileset (new TileSet(filename));
+ tilesets.insert(std::make_pair(filename, tileset.get()));
+
+ return tileset.release();
+}
+
+TileSet* TileManager::parse_tileset_definition(const Reader& reader)
+{
+ std::auto_ptr<TileSet> result(new TileSet());
+
+ lisp::ListIterator iter(&reader);
+ while(iter.next()) {
+ const std::string& token = iter.item();
+ if(token != "tileset") {
+ log_warning << "Skipping unrecognized token \"" << token << "\" in tileset definition" << std::endl;
+ continue;
+ }
+ const lisp::Lisp* tileset_reader = iter.lisp();
+
+ std::string file;
+ if (!tileset_reader->get("file", file)) {
+ log_warning << "Skipping tileset import without file name" << std::endl;
+ continue;
+ }
+
+ const TileSet *tileset = get_tileset(file);
+
+ uint32_t start = 0;
+ uint32_t end = std::numeric_limits<uint32_t>::max();
+ uint32_t offset = 0;
+ tileset_reader->get("start", start);
+ tileset_reader->get("end", end);
+ tileset_reader->get("offset", offset);
+
+ result->merge(tileset, start, end, offset);
+ }
+
+ return result.release();
+}
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2008 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_SUPERTUX_TILE_MANAGER_HPP
+#define HEADER_SUPERTUX_SUPERTUX_TILE_MANAGER_HPP
+
+#include <map>
+#include <string>
+
+#include "util/reader_fwd.hpp"
+
+class TileSet;
+
+class TileManager
+{
+private:
+ typedef std::map<std::string, TileSet*> TileSets;
+ TileSets tilesets;
+
+public:
+ TileManager();
+ ~TileManager();
+
+ TileSet* get_tileset(const std::string &filename);
+
+ TileSet* parse_tileset_definition(const Reader& reader);
+};
+
+extern TileManager *tile_manager;
+/** this is only set while loading a map */
+extern TileSet *current_tileset;
+
+#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2008 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include "supertux/tile_set.hpp"
+
+#include <stdexcept>
+#include <sstream>
+
+#include "lisp/list_iterator.hpp"
+#include "lisp/parser.hpp"
+#include "util/file_system.hpp"
+
+TileSet::TileSet()
+ : tiles_path(""), tiles_loaded(false)
+{
+ tiles.resize(1, 0);
+ tiles[0] = new Tile(this);
+}
+
+TileSet::TileSet(const std::string& filename)
+ : tiles_path(""), tiles_loaded(true)
+{
+ tiles_path = FileSystem::dirname(filename);
+
+ tiles.resize(1, 0);
+ tiles[0] = new Tile(this);
+
+ lisp::Parser parser;
+ const lisp::Lisp* root = parser.parse(filename);
+
+ const lisp::Lisp* tiles_lisp = root->get_lisp("supertux-tiles");
+ if(!tiles_lisp)
+ throw std::runtime_error("file is not a supertux tiles file.");
+
+ lisp::ListIterator iter(tiles_lisp);
+ while(iter.next()) {
+ if(iter.item() == "tile") {
+ Tile* tile = new Tile(this);
+ uint32_t id = tile->parse(*(iter.lisp()));
+
+ if(id >= tiles.size())
+ tiles.resize(id+1, 0);
+
+ if(tiles[id] != 0) {
+ log_warning << "Tile with ID " << id << " redefined" << std::endl;
+ delete tile;
+ } else {
+ tiles[id] = tile;
+ }
+ } else if(iter.item() == "tilegroup") {
+ /* tilegroups are only interesting for the editor */
+ } else if (iter.item() == "tiles") {
+ // List of ids (use 0 if the tile should be ignored)
+ std::vector<uint32_t> ids;
+ // List of attributes of the tile
+ std::vector<uint32_t> attributes;
+ // List of data for the tiles
+ std::vector<uint32_t> datas;
+ //List of frames that the tiles come in
+ std::vector<std::string> images;
+
+ // width and height of the image in tile units, this is used for two
+ // purposes:
+ // a) so we don't have to load the image here to know its dimensions
+ // b) so that the resulting 'tiles' entry is more robust,
+ // ie. enlarging the image won't break the tile id mapping
+ // FIXME: height is actually not used, since width might be enough for
+ // all purposes, still feels somewhat more natural this way
+ unsigned int width = 0;
+ unsigned int height = 0;
+
+ iter.lisp()->get("ids", ids);
+ bool has_attributes = iter.lisp()->get("attributes", attributes);
+ bool has_datas = iter.lisp()->get("datas", datas);
+
+ if(!iter.lisp()->get("image", images))
+ iter.lisp()->get( "images", images);
+
+ iter.lisp()->get("width", width);
+ iter.lisp()->get("height", height);
+
+ float animfps = 10;
+ iter.lisp()->get("anim-fps", animfps);
+
+ if(images.size() <= 0) {
+ throw std::runtime_error("No images in tile.");
+ }
+ if(animfps < 0) {
+ throw std::runtime_error("Negative fps.");
+ }
+ if (ids.size() != width*height) {
+ std::ostringstream err;
+ err << "Number of ids (" << ids.size() << ") and size of image (" << width*height
+ << ") mismatch for image '" << images[0] << "', but must be equal";
+ throw std::runtime_error(err.str());
+ }
+
+ if (has_attributes && ids.size() != attributes.size()) {
+ std::ostringstream err;
+ err << "Number of ids (" << ids.size() << ") and attributes (" << attributes.size()
+ << ") mismatch for image '" << images[0] << "', but must be equal";
+ throw std::runtime_error(err.str());
+ }
+
+ if (has_datas && ids.size() != datas.size()) {
+ std::ostringstream err;
+ err << "Number of ids (" << ids.size() << ") and datas (" << datas.size()
+ << ") mismatch for image '" << images[0] << "', but must be equal";
+ throw std::runtime_error(err.str());
+ }
+
+ for(std::vector<uint32_t>::size_type i = 0; i < ids.size() && i < width*height; ++i) {
+ if (ids[i] == 0)
+ continue;
+
+ if(ids[i] >= tiles.size())
+ tiles.resize(ids[i]+1, 0);
+
+ int x = 32*(i % width);
+ int y = 32*(i / width);
+ Tile* tile = new Tile(this, images, Rect(x, y, x + 32, y + 32),
+ (has_attributes ? attributes[i] : 0), (has_datas ? datas[i] : 0), animfps);
+ if (tiles[ids[i]] == 0) {
+ tiles[ids[i]] = tile;
+ } else {
+ log_warning << "Tile with ID " << ids[i] << " redefined" << std::endl;
+ delete tile;
+ }
+ }
+ } else if(iter.item() == "properties") {
+ // deprecated
+ } else {
+ log_warning << "Unknown symbol '" << iter.item() << "' in tileset file" << std::endl;
+ }
+ }
+ if (0)
+ { // enable this if you want to see a list of free tiles
+ log_info << "Last Tile ID is " << tiles.size()-1 << std::endl;
+ int last = -1;
+ for(int i = 0; i < int(tiles.size()); ++i)
+ {
+ if (tiles[i] == 0 && last == -1)
+ {
+ last = i;
+ }
+ else if (tiles[i] && last != -1)
+ {
+ log_info << "Free Tile IDs (" << i - last << "): " << last << " - " << i-1 << std::endl;
+ last = -1;
+ }
+ }
+ }
+ if (0)
+ { // enable this to dump the (large) list of tiles to log_debug
+ // Two dumps are identical iff the tilesets specify identical tiles
+ log_debug << "Tileset in " << filename << std::endl;
+ for(int i = 0; i < int(tiles.size()); ++i)
+ {
+ if(tiles[i] == 0)
+ continue;
+ Tile* t = tiles[i];
+ log_debug << " Tile: id " << i << ", data " << t->data << ", attributes " << t->attributes << ":" << std::endl;
+ for(std::vector<Tile::ImageSpec>::iterator im = t->imagespecs.begin(); im !=
+ t->imagespecs.end(); ++im) {
+ log_debug << " Imagespec: file " << im->file << "; rect " << im->rect << std::endl;
+ }
+ }
+ }
+}
+
+TileSet::~TileSet()
+{
+ if(tiles_loaded) {
+ for(Tiles::iterator i = tiles.begin(); i != tiles.end(); ++i)
+ delete *i;
+ }
+}
+
+void TileSet::merge(const TileSet *tileset, uint32_t start, uint32_t end,
+ uint32_t offset)
+{
+ for(uint32_t id = start; id <= end && id < tileset->tiles.size(); ++id) {
+ uint32_t dest_id = id - start + offset;
+
+ if(dest_id >= tiles.size())
+ tiles.resize(dest_id + 1, 0);
+
+ if(dest_id == 0)
+ continue;
+
+ Tile *tile = tileset->tiles[id];
+ if(tile == NULL)
+ continue;
+
+ if(tiles[dest_id] != NULL) {
+ log_warning << "tileset merge resulted in multiple definitions for id "
+ << dest_id << "(originally " << id << ")" << std::endl;
+ }
+ tiles[dest_id] = tile;
+ }
+}
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2008 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_SUPERTUX_TILE_SET_HPP
+#define HEADER_SUPERTUX_SUPERTUX_TILE_SET_HPP
+
+#include <stdint.h>
+
+#include "supertux/tile.hpp"
+#include "util/log.hpp"
+
+class TileSet
+{
+private:
+ typedef std::vector<Tile*> Tiles;
+ Tiles tiles;
+
+ std::string tiles_path;
+ bool tiles_loaded;
+
+ friend class TileManager;
+ friend class Tile;
+ TileSet(const std::string& filename);
+
+public:
+ TileSet();
+ ~TileSet();
+
+ void merge(const TileSet *tileset, uint32_t start, uint32_t end,
+ uint32_t offset);
+
+ const Tile* get(uint32_t id) const
+ {
+ assert(id < tiles.size());
+ Tile* tile = tiles[id];
+ if(!tile) {
+ log_warning << "Invalid tile: " << id << std::endl;
+ return tiles[0];
+ }
+
+ if(tile->images.size() == 0 && tile->imagespecs.size() != 0)
+ tile->load_images();
+
+ return tile;
+ }
+
+ uint32_t get_max_tileid() const
+ {
+ return tiles.size();
+ }
+};
+
+#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include <math.h>
+
+#include "supertux/timer.hpp"
+
+float game_time = 0;
+float real_time = 0;
+
+Timer::Timer()
+ : period(0), cycle_start(0), cyclic(false)
+{
+}
+
+Timer::~Timer()
+{
+}
+
+void
+Timer::start(float period, bool cyclic)
+{
+ this->period = period;
+ this->cyclic = cyclic;
+ cycle_start = game_time;
+}
+
+bool
+Timer::check()
+{
+ if(period == 0)
+ return false;
+
+ if(game_time - cycle_start >= period) {
+ if(cyclic) {
+ cycle_start = game_time - fmodf(game_time - cycle_start, period);
+ } else {
+ period = 0;
+ }
+ return true;
+ }
+
+ return false;
+}
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_SUPERTUX_TIMER_HPP
+#define HEADER_SUPERTUX_SUPERTUX_TIMER_HPP
+
+extern float game_time;
+extern float real_time;
+
+/**
+ * Simple timer designed to be used in the update functions of objects
+ */
+class Timer
+{
+public:
+ Timer();
+ ~Timer();
+
+ /** start the timer with the given period (in seconds).
+ * If cyclic=true then the timer will be reset after each period.
+ * Set period to zero if you want to disable the timer.
+ */
+ void start(float period, bool cyclic = false);
+ /** returns true if a period (or more) passed since start call or last
+ * successful check
+ */
+ bool check();
+ /** stop the timer */
+ void stop()
+ { start(0); }
+
+ /** returns the period of the timer or 0 if it isn't started */
+ float get_period() const
+ { return period; }
+ float get_timeleft() const
+ { return period - (game_time - cycle_start); }
+ float get_timegone() const
+ { return game_time - cycle_start; }
+ bool started() const
+ { return period != 0 && get_timeleft() > 0; }
+
+private:
+ float period;
+ float cycle_start;
+ bool cyclic;
+};
+
+#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include <version.h>
+
+#include "supertux/title.hpp"
+
+#include <algorithm>
+#include <physfs.h>
+
+#include "addon/addon_manager.hpp"
+#include "audio/sound_manager.hpp"
+#include "gui/menu.hpp"
+#include "lisp/parser.hpp"
+#include "lisp/lisp.hpp"
+#include "object/camera.hpp"
+#include "object/player.hpp"
+#include "supertux/fadeout.hpp"
+#include "supertux/gameconfig.hpp"
+#include "supertux/main.hpp"
+#include "supertux/mainloop.hpp"
+#include "supertux/options_menu.hpp"
+#include "supertux/resources.hpp"
+#include "supertux/sector.hpp"
+#include "supertux/textscroller.hpp"
+#include "supertux/world.hpp"
+#include "util/file_system.hpp"
+#include "util/gettext.hpp"
+#include "video/drawing_context.hpp"
+
+enum MainMenuIDs {
+ MNID_STARTGAME,
+ MNID_LEVELS_CONTRIB,
+ MNID_ADDONS,
+ MNID_OPTIONMENU,
+ MNID_LEVELEDITOR,
+ MNID_CREDITS,
+ MNID_QUITMAINMENU
+};
+
+void
+TitleScreen::update_load_game_menu()
+{
+}
+
+void
+TitleScreen::free_contrib_menu()
+{
+ for(std::vector<World*>::iterator i = contrib_worlds.begin();
+ i != contrib_worlds.end(); ++i)
+ delete *i;
+
+ contrib_worlds.clear();
+}
+
+void
+TitleScreen::generate_contrib_menu()
+{
+ /** Generating contrib levels list by making use of Level Subset */
+ std::vector<std::string> level_worlds;
+ char** files = PHYSFS_enumerateFiles("levels/");
+ for(const char* const* filename = files; *filename != 0; ++filename) {
+ std::string filepath = std::string("levels/") + *filename;
+ if(PHYSFS_isDirectory(filepath.c_str()))
+ level_worlds.push_back(filepath);
+ }
+ PHYSFS_freeList(files);
+
+ free_contrib_menu();
+ contrib_menu.reset(new Menu());
+
+ contrib_menu->add_label(_("Contrib Levels"));
+ contrib_menu->add_hl();
+
+ int i = 0;
+ for (std::vector<std::string>::iterator it = level_worlds.begin();
+ it != level_worlds.end(); ++it) {
+ try {
+ std::auto_ptr<World> world (new World());
+ world->load(*it + "/info");
+ if(world->hide_from_contribs) {
+ continue;
+ }
+ contrib_menu->add_entry(i++, world->title);
+ contrib_worlds.push_back(world.release());
+ } catch(std::exception& e) {
+ log_warning << "Couldn't parse levelset info for '" << *it << "': " << e.what() << std::endl;
+ }
+ }
+
+ contrib_menu->add_hl();
+ contrib_menu->add_back(_("Back"));
+}
+
+std::string
+TitleScreen::get_level_name(const std::string& filename)
+{
+ try {
+ lisp::Parser parser;
+ const lisp::Lisp* root = parser.parse(filename);
+
+ const lisp::Lisp* level = root->get_lisp("supertux-level");
+ if(!level)
+ return "";
+
+ std::string name;
+ level->get("name", name);
+ return name;
+ } catch(std::exception& e) {
+ log_warning << "Problem getting name of '" << filename << "': "
+ << e.what() << std::endl;
+ return "";
+ }
+}
+
+void
+TitleScreen::check_levels_contrib_menu()
+{
+ int index = contrib_menu->check();
+ if (index == -1)
+ return;
+
+ current_world = contrib_worlds[index];
+
+ if(!current_world->is_levelset) {
+ start_game();
+ } else {
+ contrib_world_menu.reset(new Menu());
+
+ contrib_world_menu->add_label(current_world->title);
+ contrib_world_menu->add_hl();
+
+ for (unsigned int i = 0; i < current_world->get_num_levels(); ++i)
+ {
+ /** get level's title */
+ std::string filename = current_world->get_level_filename(i);
+ std::string title = get_level_name(filename);
+ contrib_world_menu->add_entry(i, title);
+ }
+
+ contrib_world_menu->add_hl();
+ contrib_world_menu->add_back(_("Back"));
+
+ Menu::push_current(contrib_world_menu.get());
+ }
+}
+
+void
+TitleScreen::check_contrib_world_menu()
+{
+ int index = contrib_world_menu->check();
+ if (index != -1) {
+ if (contrib_world_menu->get_item_by_id(index).kind == MN_ACTION) {
+ sound_manager->stop_music();
+ GameSession* session =
+ new GameSession(current_world->get_level_filename(index));
+ g_main_loop->push_screen(session);
+ }
+ }
+}
+
+namespace {
+bool generate_addons_menu_sorter(const Addon* a1, const Addon* a2)
+{
+ return a1->title < a2->title;
+}
+
+const int ADDON_LIST_START_ID = 10;
+}
+
+void
+TitleScreen::generate_addons_menu()
+{
+ AddonManager& adm = AddonManager::get_instance();
+
+ // refresh list of addons
+ addons = adm.get_addons();
+
+ // sort list
+ std::sort(addons.begin(), addons.end(), generate_addons_menu_sorter);
+
+ // (re)generate menu
+ free_addons_menu();
+ addons_menu.reset(new Menu());
+
+ addons_menu->add_label(_("Add-ons"));
+ addons_menu->add_hl();
+
+#ifdef HAVE_LIBCURL
+ addons_menu->add_entry(0, std::string(_("Check Online")));
+#else
+ addons_menu->add_inactive(0, std::string(_("Check Online (disabled)")));
+#endif
+
+ //addons_menu->add_hl();
+
+ for (unsigned int i = 0; i < addons.size(); i++) {
+ const Addon& addon = *addons[i];
+ std::string text = "";
+ if (addon.kind != "") text += addon.kind + " ";
+ text += std::string("\"") + addon.title + "\"";
+ if (addon.author != "") text += " by \"" + addon.author + "\"";
+ addons_menu->add_toggle(ADDON_LIST_START_ID + i, text, addon.loaded);
+ }
+
+ addons_menu->add_hl();
+ addons_menu->add_back(_("Back"));
+}
+
+void
+TitleScreen::check_addons_menu()
+{
+ int index = addons_menu->check();
+ if (index == -1) return;
+
+ // check if "Check Online" was chosen
+ if (index == 0) {
+ try {
+ AddonManager::get_instance().check_online();
+ generate_addons_menu();
+ Menu::set_current(addons_menu.get());
+ addons_menu->set_active_item(index);
+ }
+ catch (std::runtime_error e) {
+ log_warning << "Check for available Add-ons failed: " << e.what() << std::endl;
+ }
+ return;
+ }
+
+ // if one of the Addons listed was chosen, take appropriate action
+ if ((index >= ADDON_LIST_START_ID) && (index < ADDON_LIST_START_ID) + addons.size()) {
+ Addon& addon = *addons[index - ADDON_LIST_START_ID];
+ if (!addon.installed) {
+ try {
+ AddonManager::get_instance().install(&addon);
+ }
+ catch (std::runtime_error e) {
+ log_warning << "Installing Add-on failed: " << e.what() << std::endl;
+ }
+ addons_menu->set_toggled(index, addon.loaded);
+ } else if (!addon.loaded) {
+ try {
+ AddonManager::get_instance().enable(&addon);
+ }
+ catch (std::runtime_error e) {
+ log_warning << "Enabling Add-on failed: " << e.what() << std::endl;
+ }
+ addons_menu->set_toggled(index, addon.loaded);
+ } else {
+ try {
+ AddonManager::get_instance().disable(&addon);
+ }
+ catch (std::runtime_error e) {
+ log_warning << "Disabling Add-on failed: " << e.what() << std::endl;
+ }
+ addons_menu->set_toggled(index, addon.loaded);
+ }
+ }
+}
+
+void
+TitleScreen::free_addons_menu()
+{
+}
+
+void
+TitleScreen::make_tux_jump()
+{
+ static bool jumpWasReleased = true;
+ Sector* sector = titlesession->get_current_sector();
+ Player* tux = sector->player;
+
+ controller->update();
+ controller->press(Controller::RIGHT);
+
+ // Check if we should press the jump button
+ Rect lookahead = tux->get_bbox();
+ lookahead.p2.x += 96;
+ bool pathBlocked = !sector->is_free_of_statics(lookahead);
+ if ((pathBlocked && jumpWasReleased) || !tux->on_ground()) {
+ controller->press(Controller::JUMP);
+ jumpWasReleased = false;
+ } else {
+ jumpWasReleased = true;
+ }
+
+ // Wrap around at the end of the level back to the beginning
+ if(sector->get_width() - 320 < tux->get_pos().x) {
+ sector->activate("main");
+ sector->camera->reset(tux->get_pos());
+ }
+}
+
+TitleScreen::TitleScreen()
+{
+ controller.reset(new CodeController());
+ titlesession.reset(new GameSession("levels/misc/menu.stl"));
+
+ Player* player = titlesession->get_current_sector()->player;
+ player->set_controller(controller.get());
+ player->set_speedlimit(230); //MAX_WALK_XM
+
+ generate_main_menu();
+
+ frame = std::auto_ptr<Surface>(new Surface("images/engine/menu/frame.png"));
+}
+
+void
+TitleScreen::generate_main_menu()
+{
+ main_menu.reset(new Menu());
+ main_menu->set_pos(SCREEN_WIDTH/2, SCREEN_HEIGHT/2 + 35);
+ main_menu->add_entry(MNID_STARTGAME, _("Start Game"));
+ main_menu->add_entry(MNID_LEVELS_CONTRIB, _("Contrib Levels"));
+ main_menu->add_entry(MNID_ADDONS, _("Add-ons"));
+ main_menu->add_submenu(_("Options"), get_options_menu());
+ main_menu->add_entry(MNID_CREDITS, _("Credits"));
+ main_menu->add_entry(MNID_QUITMAINMENU, _("Quit"));
+}
+
+TitleScreen::~TitleScreen()
+{
+}
+
+void
+TitleScreen::setup()
+{
+ player_status->reset();
+
+ Sector* sector = titlesession->get_current_sector();
+ if(Sector::current() != sector) {
+ sector->play_music(LEVEL_MUSIC);
+ sector->activate(sector->player->get_pos());
+ }
+
+ Menu::set_current(main_menu.get());
+}
+
+void
+TitleScreen::leave()
+{
+ Sector* sector = titlesession->get_current_sector();
+ sector->deactivate();
+ Menu::set_current(NULL);
+}
+
+void
+TitleScreen::draw(DrawingContext& context)
+{
+ Sector* sector = titlesession->get_current_sector();
+ sector->draw(context);
+
+ // FIXME: Add something to scale the frame to the resolution of the screen
+ context.draw_surface(frame.get(), Vector(0,0),LAYER_FOREGROUND1);
+
+ context.draw_text(small_font, "SuperTux " PACKAGE_VERSION "\n",
+ Vector(5, SCREEN_HEIGHT - 50), ALIGN_LEFT, LAYER_FOREGROUND1);
+ context.draw_text(small_font,
+ _(
+ "Copyright (c) 2007 SuperTux Devel Team\n"
+ "This game comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to\n"
+ "redistribute it under certain conditions; see the file COPYING for details.\n"
+ ),
+ Vector(5, SCREEN_HEIGHT - 50 + small_font->get_height() + 5),
+ ALIGN_LEFT, LAYER_FOREGROUND1);
+}
+
+void
+TitleScreen::update(float elapsed_time)
+{
+ g_main_loop->set_speed(0.6f);
+ Sector* sector = titlesession->get_current_sector();
+ sector->update(elapsed_time);
+
+ make_tux_jump();
+
+ Menu* menu = Menu::current();
+ if(menu) {
+ if(menu == main_menu.get()) {
+ switch (main_menu->check()) {
+ case MNID_STARTGAME:
+ // Start Game, ie. goto the slots menu
+ if(main_world.get() == NULL) {
+ main_world.reset(new World());
+ main_world->load("levels/world1/info");
+ }
+ current_world = main_world.get();
+ start_game();
+ break;
+
+ case MNID_LEVELS_CONTRIB:
+ // Contrib Menu
+ generate_contrib_menu();
+ Menu::push_current(contrib_menu.get());
+ break;
+
+ case MNID_ADDONS:
+ // Add-ons Menu
+ generate_addons_menu();
+ Menu::push_current(addons_menu.get());
+ break;
+
+ case MNID_CREDITS:
+ Menu::set_current(NULL);
+ g_main_loop->push_screen(new TextScroller("credits.txt"),
+ new FadeOut(0.5));
+ break;
+
+ case MNID_QUITMAINMENU:
+ g_main_loop->quit(new FadeOut(0.25));
+ sound_manager->stop_music(0.25);
+ break;
+ }
+ } else if(menu == contrib_menu.get()) {
+ check_levels_contrib_menu();
+ } else if(menu == addons_menu.get()) {
+ check_addons_menu();
+ } else if (menu == contrib_world_menu.get()) {
+ check_contrib_world_menu();
+ }
+ }
+
+ // reopen menu if user closed it (so that the app doesn't close when user
+ // accidently hit ESC)
+ if(Menu::current() == 0 && g_main_loop->has_no_pending_fadeout()) {
+ generate_main_menu();
+ Menu::set_current(main_menu.get());
+ }
+}
+
+void
+TitleScreen::start_game()
+{
+ Menu::set_current(NULL);
+ std::string basename = current_world->get_basedir();
+ basename = basename.substr(0, basename.length()-1);
+ std::string worlddirname = FileSystem::basename(basename);
+ std::ostringstream stream;
+ stream << "profile" << g_config->profile << "/" << worlddirname << ".stsg";
+ std::string slotfile = stream.str();
+
+ try {
+ current_world->set_savegame_filename(slotfile);
+ current_world->run();
+ } catch(std::exception& e) {
+ log_fatal << "Couldn't start world: " << e.what() << std::endl;
+ }
+}
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_SUPERTUX_TITLE_HPP
+#define HEADER_SUPERTUX_SUPERTUX_TITLE_HPP
+
+#include "addon/addon.hpp"
+#include "supertux/game_session.hpp"
+
+class Menu;
+class World;
+class CodeController;
+
+/**
+ * Screen that displays the SuperTux logo, lets players start a new game, etc.
+ */
+class TitleScreen : public Screen
+{
+public:
+ TitleScreen();
+ virtual ~TitleScreen();
+
+ virtual void setup();
+ virtual void leave();
+
+ virtual void draw(DrawingContext& context);
+
+ virtual void update(float elapsed_time);
+
+private:
+ std::string get_level_name(const std::string& levelfile);
+ void start_game();
+ void make_tux_jump();
+ void update_load_game_menu();
+ void generate_main_menu();
+ void generate_contrib_menu();
+ void check_levels_contrib_menu();
+ void check_contrib_world_menu();
+ void free_contrib_menu();
+ void generate_addons_menu();
+ void check_addons_menu();
+ void free_addons_menu();
+
+ std::auto_ptr<Menu> main_menu;
+ std::auto_ptr<Menu> contrib_menu;
+ std::auto_ptr<Menu> contrib_world_menu;
+ std::auto_ptr<World> main_world;
+ std::vector<World*> contrib_worlds;
+ std::auto_ptr<Menu> addons_menu;
+ std::vector<Addon*> addons; /**< shown list of Add-ons */
+ World* current_world;
+
+ std::auto_ptr<Surface> frame;
+ std::auto_ptr<CodeController> controller;
+ std::auto_ptr<GameSession> titlesession;
+};
+
+#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include "lisp/parser.hpp"
+#include "lisp/writer.hpp"
+#include "physfs/physfs_stream.hpp"
+#include "scripting/serialize.hpp"
+#include "scripting/squirrel_util.hpp"
+#include "supertux/mainloop.hpp"
+#include "supertux/player_status.hpp"
+#include "supertux/world.hpp"
+#include "util/file_system.hpp"
+#include "worldmap/worldmap.hpp"
+
+static bool has_suffix(const std::string& data, const std::string& suffix)
+{
+ if (data.length() >= suffix.length())
+ return data.compare(data.length() - suffix.length(), suffix.length(), suffix) == 0;
+ else
+ return false;
+}
+
+World* World::current_ = NULL;
+
+World::World()
+{
+ is_levelset = true;
+ hide_from_contribs = false;
+ sq_resetobject(&world_thread);
+}
+
+World::~World()
+{
+ sq_release(Scripting::global_vm, &world_thread);
+ if(current_ == this)
+ current_ = NULL;
+}
+
+void
+World::set_savegame_filename(const std::string& filename)
+{
+ this->savegame_filename = filename;
+ // make sure the savegame directory exists
+ std::string dirname = FileSystem::dirname(filename);
+ if(!PHYSFS_exists(dirname.c_str())) {
+ if(PHYSFS_mkdir(dirname.c_str())) {
+ std::ostringstream msg;
+ msg << "Couldn't create directory for savegames '"
+ << dirname << "': " <<PHYSFS_getLastError();
+ throw std::runtime_error(msg.str());
+ }
+ }
+
+ if(!PHYSFS_isDirectory(dirname.c_str())) {
+ std::ostringstream msg;
+ msg << "Savegame path '" << dirname << "' is not a directory";
+ throw std::runtime_error(msg.str());
+ }
+}
+
+void
+World::load(const std::string& filename)
+{
+ basedir = FileSystem::dirname(filename);
+
+ lisp::Parser parser;
+ const lisp::Lisp* root = parser.parse(filename);
+
+ const lisp::Lisp* info = root->get_lisp("supertux-world");
+ if(info == NULL)
+ info = root->get_lisp("supertux-level-subset");
+ if(info == NULL)
+ throw std::runtime_error("File is not a world or levelsubset file");
+
+ hide_from_contribs = false;
+ is_levelset = true;
+
+ info->get("title", title);
+ info->get("description", description);
+ info->get("levelset", is_levelset);
+ info->get("levels", levels);
+ info->get("hide-from-contribs", hide_from_contribs);
+
+ // Level info file doesn't define any levels, so read the
+ // directory to see what we can find
+
+ std::string path = basedir;
+ char** files = PHYSFS_enumerateFiles(path.c_str());
+ if(!files) {
+ log_warning << "Couldn't read subset dir '" << path << "'" << std::endl;
+ return;
+ }
+
+ for(const char* const* filename = files; *filename != 0; ++filename) {
+ if(has_suffix(*filename, ".stl")) {
+ levels.push_back(path + *filename);
+ }
+ }
+ PHYSFS_freeList(files);
+}
+
+void
+World::run()
+{
+ using namespace Scripting;
+
+ current_ = this;
+
+ // create new squirrel table for persistent game state
+ HSQUIRRELVM vm = Scripting::global_vm;
+
+ sq_pushroottable(vm);
+ sq_pushstring(vm, "state", -1);
+ sq_newtable(vm);
+ if(SQ_FAILED(sq_createslot(vm, -3)))
+ throw Scripting::SquirrelError(vm, "Couldn't create state table");
+ sq_pop(vm, 1);
+
+ load_state();
+
+ std::string filename = basedir + "/world.nut";
+ try {
+ IFileStream in(filename);
+
+ sq_release(global_vm, &world_thread);
+ world_thread = create_thread(global_vm);
+ compile_and_run(object_to_vm(world_thread), in, filename);
+ } catch(std::exception& ) {
+ // fallback: try to load worldmap worldmap.stwm
+ using namespace WorldMapNS;
+ g_main_loop->push_screen(new WorldMap(basedir + "worldmap.stwm"));
+ }
+}
+
+void
+World::save_state()
+{
+ using namespace Scripting;
+
+ lisp::Writer writer(savegame_filename);
+
+ writer.start_list("supertux-savegame");
+ writer.write("version", 1);
+
+ using namespace WorldMapNS;
+ if(WorldMap::current() != NULL) {
+ std::ostringstream title;
+ title << WorldMap::current()->get_title();
+ title << " (" << WorldMap::current()->solved_level_count()
+ << "/" << WorldMap::current()->level_count() << ")";
+ writer.write("title", title.str());
+ }
+
+ writer.start_list("tux");
+ player_status->write(writer);
+ writer.end_list("tux");
+
+ writer.start_list("state");
+
+ sq_pushroottable(global_vm);
+ sq_pushstring(global_vm, "state", -1);
+ if(SQ_SUCCEEDED(sq_get(global_vm, -2))) {
+ Scripting::save_squirrel_table(global_vm, -1, writer);
+ sq_pop(global_vm, 1);
+ }
+ sq_pop(global_vm, 1);
+ writer.end_list("state");
+
+ writer.end_list("supertux-savegame");
+}
+
+void
+World::load_state()
+{
+ using namespace Scripting;
+
+ try {
+ lisp::Parser parser;
+ const lisp::Lisp* root = parser.parse(savegame_filename);
+
+ const lisp::Lisp* lisp = root->get_lisp("supertux-savegame");
+ if(lisp == NULL)
+ throw std::runtime_error("file is not a supertux-savegame file");
+
+ int version = 1;
+ lisp->get("version", version);
+ if(version != 1)
+ throw std::runtime_error("incompatible savegame version");
+
+ const lisp::Lisp* tux = lisp->get_lisp("tux");
+ if(tux == NULL)
+ throw std::runtime_error("No tux section in savegame");
+ player_status->read(*tux);
+
+ const lisp::Lisp* state = lisp->get_lisp("state");
+ if(state == NULL)
+ throw std::runtime_error("No state section in savegame");
+
+ sq_pushroottable(global_vm);
+ sq_pushstring(global_vm, "state", -1);
+ if(SQ_FAILED(sq_deleteslot(global_vm, -2, SQFalse)))
+ sq_pop(global_vm, 1);
+
+ sq_pushstring(global_vm, "state", -1);
+ sq_newtable(global_vm);
+ load_squirrel_table(global_vm, -1, state);
+ if(SQ_FAILED(sq_createslot(global_vm, -3)))
+ throw std::runtime_error("Couldn't create state table");
+ sq_pop(global_vm, 1);
+ } catch(std::exception& e) {
+ log_debug << "Couldn't load savegame: " << e.what() << std::endl;
+ }
+}
+
+const std::string&
+World::get_level_filename(unsigned int i) const
+{
+ return levels[i];
+}
+
+unsigned int
+World::get_num_levels() const
+{
+ return levels.size();
+}
+
+const std::string&
+World::get_basedir() const
+{
+ return basedir;
+}
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_SUPERTUX_WORLD_HPP
+#define HEADER_SUPERTUX_SUPERTUX_WORLD_HPP
+
+#include <squirrel.h>
+#include <string>
+#include <vector>
+
+class World
+{
+private:
+ std::vector<std::string> levels;
+ std::string basedir;
+ std::string savegame_filename;
+ /// squirrel table that saves persistent state (about the world)
+ HSQOBJECT state_table;
+ HSQOBJECT world_thread;
+ static World* current_;
+
+public:
+ World();
+ ~World();
+
+ void set_savegame_filename(const std::string& filename);
+ void load(const std::string& filename);
+
+ void save_state();
+ void load_state();
+
+ const std::string& get_level_filename(unsigned int i) const;
+ unsigned int get_num_levels() const;
+
+ const std::string& get_basedir() const;
+
+ static World* current()
+ {
+ return current_;
+ }
+
+ void run();
+
+ std::string title;
+ std::string description;
+ bool hide_from_contribs;
+ bool is_levelset;
+};
+
+#endif
+
+/* EOF */
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-#include <config.h>
-
-#include "textscroller.hpp"
-
-#include <stdexcept>
-#include "log.hpp"
-#include "mainloop.hpp"
-#include "resources.hpp"
-#include "video/font.hpp"
-#include "video/drawing_context.hpp"
-#include "video/surface.hpp"
-#include "gui/menu.hpp"
-#include "lisp/parser.hpp"
-#include "lisp/lisp.hpp"
-#include "audio/sound_manager.hpp"
-#include "main.hpp"
-#include "fadeout.hpp"
-#include "control/joystickkeyboardcontroller.hpp"
-
-static const float DEFAULT_SPEED = 20;
-static const float LEFT_BORDER = 50;
-static const float SCROLL = 60;
-static const float ITEMS_SPACE = 4;
-
-TextScroller::TextScroller(const std::string& filename)
-{
- defaultspeed = DEFAULT_SPEED;
- speed = defaultspeed;
-
- std::string text;
- std::string background_file;
-
- lisp::Parser parser;
- try {
- const lisp::Lisp* root = parser.parse(filename);
-
- const lisp::Lisp* text_lisp = root->get_lisp("supertux-text");
- if(!text_lisp)
- throw std::runtime_error("File isn't a supertux-text file");
-
- if(!text_lisp->get("text", text))
- throw std::runtime_error("file doesn't contain a text field");
- if(!text_lisp->get("background", background_file))
- throw std::runtime_error("file doesn't contain a background file");
- text_lisp->get("speed", defaultspeed);
- text_lisp->get("music", music);
- } catch(std::exception& e) {
- std::ostringstream msg;
- msg << "Couldn't load file '" << filename << "': " << e.what() << std::endl;
- throw std::runtime_error(msg.str());
- }
-
- // Split text string lines into a vector
- lines = InfoBoxLine::split(text, SCREEN_WIDTH - 2*LEFT_BORDER);
-
- // load background image
- background.reset(new Surface("images/background/" + background_file));
-
- scroll = 0;
- fading = false;
-}
-
-TextScroller::~TextScroller()
-{
- for(std::vector<InfoBoxLine*>::iterator i = lines.begin(); i != lines.end(); i++) delete *i;
-}
-
-void
-TextScroller::setup()
-{
- sound_manager->play_music(music);
-}
-
-void
-TextScroller::update(float elapsed_time)
-{
- if(main_controller->hold(Controller::UP)) {
- speed = -defaultspeed*5;
- } else if(main_controller->hold(Controller::DOWN)) {
- speed = defaultspeed*5;
- } else {
- speed = defaultspeed;
- }
- if(main_controller->pressed(Controller::JUMP)
- || main_controller->pressed(Controller::ACTION)
- || main_controller->pressed(Controller::MENU_SELECT))
- scroll += SCROLL;
- if(main_controller->pressed(Controller::PAUSE_MENU)) {
- main_loop->exit_screen(new FadeOut(0.5));
- }
-
- scroll += speed * elapsed_time;
-
- if(scroll < 0)
- scroll = 0;
-}
-
-void
-TextScroller::draw(DrawingContext& context)
-{
- context.draw_filled_rect(Vector(0, 0), Vector(SCREEN_WIDTH, SCREEN_HEIGHT),
- Color(0.6f, 0.7f, 0.8f, 0.5f), 0);
- context.draw_surface(background.get(), Vector(SCREEN_WIDTH/2 - background->get_width()/2 , SCREEN_HEIGHT/2 - background->get_height()/2), 0);
-
- float y = SCREEN_HEIGHT - scroll;
- for(size_t i = 0; i < lines.size(); i++) {
- if (y + lines[i]->get_height() >= 0 && SCREEN_HEIGHT - y >= 0) {
- lines[i]->draw(context, Rect(LEFT_BORDER, y, SCREEN_WIDTH - 2*LEFT_BORDER, y), LAYER_GUI);
- }
-
- y += lines[i]->get_height();
- }
-
- if(y < 0 && !fading ) {
- fading = true;
- main_loop->exit_screen(new FadeOut(0.5));
- }
-}
-
-InfoBox::InfoBox(const std::string& text)
- : firstline(0)
-{
- // Split text string lines into a vector
- lines = InfoBoxLine::split(text, 400);
-
- try
- {
- // get the arrow sprites
- arrow_scrollup = new Surface("images/engine/menu/scroll-up.png");
- arrow_scrolldown = new Surface("images/engine/menu/scroll-down.png");
- }
- catch (std::exception& e)
- {
- log_warning << "Could not load scrolling images: " << e.what() << std::endl;
- arrow_scrollup = 0;
- arrow_scrolldown = 0;
- }
-}
-
-InfoBox::~InfoBox()
-{
- for(std::vector<InfoBoxLine*>::iterator i = lines.begin();
- i != lines.end(); i++)
- delete *i;
- delete arrow_scrollup;
- delete arrow_scrolldown;
-}
-
-void
-InfoBox::draw(DrawingContext& context)
-{
- float x1 = SCREEN_WIDTH/2-200;
- float y1 = SCREEN_HEIGHT/2-200;
- float width = 400;
- float height = 200;
-
- context.draw_filled_rect(Vector(x1, y1), Vector(width, height),
- Color(0.6f, 0.7f, 0.8f, 0.5f), LAYER_GUI-1);
-
- float y = y1;
- bool linesLeft = false;
- for(size_t i = firstline; i < lines.size(); ++i) {
- if(y >= y1 + height) {
- linesLeft = true;
- break;
- }
-
- lines[i]->draw(context, Rect(x1, y, x1+width, y), LAYER_GUI);
- y += lines[i]->get_height();
- }
-
- {
- // draw the scrolling arrows
- if (arrow_scrollup && firstline > 0)
- context.draw_surface(arrow_scrollup,
- Vector( x1 + width - arrow_scrollup->get_width(), // top-right corner of box
- y1), LAYER_GUI);
-
- if (arrow_scrolldown && linesLeft && firstline < lines.size()-1)
- context.draw_surface(arrow_scrolldown,
- Vector( x1 + width - arrow_scrolldown->get_width(), // bottom-light corner of box
- y1 + height - arrow_scrolldown->get_height()),
- LAYER_GUI);
- }
-}
-
-void
-InfoBox::scrollup()
-{
- if(firstline > 0)
- firstline--;
-}
-
-void
-InfoBox::scrolldown()
-{
- if(firstline < lines.size()-1)
- firstline++;
-}
-
-void
-InfoBox::pageup()
-{
-}
-
-void
-InfoBox::pagedown()
-{
-}
-
-namespace {
-Font* get_font_by_format_char(char format_char) {
- switch(format_char)
- {
- case ' ':
- return small_font;
- break;
- case '-':
- return big_font;
- break;
- case '\t':
- case '*':
- case '#':
- case '!':
- return normal_font;
- break;
- default:
- return normal_font;
- log_warning << "Unknown format_char: '" << format_char << "'" << std::endl;
- break;
- }
-}
-
-Color get_color_by_format_char(char format_char) {
- switch(format_char)
- {
- case ' ':
- return TextScroller::small_color;
- break;
- case '-':
- return TextScroller::heading_color;
- break;
- case '*':
- return TextScroller::reference_color;
- case '\t':
- case '#':
- case '!':
- return TextScroller::normal_color;
- break;
- default:
- return Color(0,0,0);
- log_warning << "Unknown format_char: '" << format_char << "'" << std::endl;
- break;
- }
-}
-
-InfoBoxLine::LineType get_linetype_by_format_char(char format_char) {
- switch(format_char)
- {
- case ' ':
- return InfoBoxLine::SMALL;
- break;
- case '\t':
- return InfoBoxLine::NORMAL;
- break;
- case '-':
- return InfoBoxLine::HEADING;
- break;
- case '*':
- return InfoBoxLine::REFERENCE;
- break;
- case '#':
- return InfoBoxLine::NORMAL_LEFT;
- break;
- case '!':
- return InfoBoxLine::IMAGE;
- break;
- default:
- return InfoBoxLine::SMALL;
- log_warning << "Unknown format_char: '" << format_char << "'" << std::endl;
- break;
- }
-}
-}
-
-InfoBoxLine::InfoBoxLine(char format_char, const std::string& text) : lineType(NORMAL), font(normal_font), text(text), image(0)
-{
- font = get_font_by_format_char(format_char);
- lineType = get_linetype_by_format_char(format_char);
- color = get_color_by_format_char(format_char);
- if (lineType == IMAGE) image = new Surface(text);
-}
-
-InfoBoxLine::~InfoBoxLine()
-{
- delete image;
-}
-
-const std::vector<InfoBoxLine*>
-InfoBoxLine::split(const std::string& text, float width)
-{
- std::vector<InfoBoxLine*> lines;
-
- std::string::size_type i = 0;
- std::string::size_type l;
- char format_char = '#';
- while(i < text.size()) {
- // take care of empty lines - represent them as blank lines of normal text
- if (text[i] == '\n') {
- lines.push_back(new InfoBoxLine('\t', ""));
- i++;
- continue;
- }
-
- // extract the format_char
- format_char = text[i];
- i++;
- if (i >= text.size()) break;
-
- // extract one line
- l = text.find("\n", i);
- if (l == std::string::npos) l=text.size();
- std::string s = text.substr(i, l-i);
- i = l+1;
-
- // if we are dealing with an image, just store the line
- if (format_char == '!') {
- lines.push_back(new InfoBoxLine(format_char, s));
- continue;
- }
-
- // append wrapped parts of line into list
- std::string overflow;
- do {
- Font* font = get_font_by_format_char(format_char);
- std::string s2 = s;
- if (font) s2 = font->wrap_to_width(s2, width, &overflow);
- lines.push_back(new InfoBoxLine(format_char, s2));
- s = overflow;
- } while (s.length() > 0);
- }
-
- return lines;
-}
-
-void
-InfoBoxLine::draw(DrawingContext& context, const Rect& bbox, int layer)
-{
- Vector position = bbox.p1;
- switch (lineType) {
- case IMAGE:
- context.draw_surface(image, Vector( (bbox.p1.x + bbox.p2.x - image->get_width()) / 2, position.y), layer);
- break;
- case NORMAL_LEFT:
- context.draw_text(font, text, Vector(position.x, position.y), ALIGN_LEFT, layer, color);
- break;
- default:
- context.draw_text(font, text, Vector((bbox.p1.x + bbox.p2.x) / 2, position.y), ALIGN_CENTER, layer, color);
- break;
- }
-}
-
-float
-InfoBoxLine::get_height()
-{
- switch (lineType) {
- case IMAGE:
- return image->get_height() + ITEMS_SPACE;
- case NORMAL_LEFT:
- return font->get_height() + ITEMS_SPACE;
- default:
- return font->get_height() + ITEMS_SPACE;
- }
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-
-#ifndef __TEXTSCROLLER_H__
-#define __TEXTSCROLLER_H__
-
-#include <vector>
-#include <string>
-#include <map>
-#include <memory>
-
-#include "screen.hpp"
-#include "math/vector.hpp"
-#include "math/rect.hpp"
-#include "video/color.hpp"
-
-class DrawingContext;
-class Surface;
-class Font;
-
-/**
- * Helper class for InfoBox: Represents a line of text
- */
-class InfoBoxLine
-{
-public:
- enum LineType { NORMAL, NORMAL_LEFT, SMALL, HEADING, REFERENCE, IMAGE};
-
- InfoBoxLine(char format_char, const std::string& text);
- ~InfoBoxLine();
-
- void draw(DrawingContext& context, const Rect& bbox, int layer);
- float get_height();
-
- static const std::vector<InfoBoxLine*> split(const std::string& text, float width);
-
-private:
- InfoBoxLine::LineType lineType;
- Font* font;
- Color color;
- std::string text;
- Surface* image;
-};
-
-/** This class is displaying a box with information text inside the game
- */
-class InfoBox
-{
-public:
- InfoBox(const std::string& text);
- ~InfoBox();
-
- void draw(DrawingContext& context);
- void scrolldown();
- void scrollup();
- void pagedown();
- void pageup();
-
-private:
- size_t firstline;
- std::vector<InfoBoxLine*> lines;
- std::map<std::string, Surface*> images;
- Surface* arrow_scrollup;
- Surface* arrow_scrolldown;
-};
-
-/**
- * Screen that displays intro text, extro text, etc.
- */
-class TextScroller : public Screen
-{
-public:
- TextScroller(const std::string& file);
- virtual ~TextScroller();
-
- void setup();
- void draw(DrawingContext& context);
- void update(float elapsed_time);
-
- static Color small_color;
- static Color heading_color;
- static Color reference_color;
- static Color normal_color;
-private:
- float defaultspeed;
- float speed;
- std::string music;
- std::auto_ptr<Surface> background;
- std::vector<InfoBoxLine*> lines;
- float scroll;
- bool fading;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-
-#include <config.h>
-
-#include "tile.hpp"
-
-#include <math.h>
-#include <assert.h>
-#include <iostream>
-#include <stdexcept>
-
-#include "lisp/lisp.hpp"
-#include "tile_set.hpp"
-#include "timer.hpp"
-#include "math/vector.hpp"
-#include "video/drawing_context.hpp"
-#include "log.hpp"
-
-
-Tile::Tile(const TileSet *new_tileset)
- : tileset(new_tileset), attributes(0), data(0), anim_fps(1)
-{
-}
-
-Tile::Tile(const TileSet *new_tileset, std::vector<std::string> images, Rect rect, Uint32 attributes, Uint32 data, float animfps)
- : tileset(new_tileset), attributes(attributes), data(data), anim_fps(animfps)
-{
- for(std::vector<std::string>::iterator i = images.begin(); i != images.end(); ++i) {
- imagespecs.push_back(ImageSpec(*i, rect));
- }
- correct_attributes();
-}
-
-Tile::~Tile()
-{
- for(std::vector<Surface*>::iterator i = images.begin(); i != images.end();
- ++i) {
- delete *i;
- }
-}
-
-uint32_t
-Tile::parse(const lisp::Lisp& reader)
-{
- uint32_t id;
- if(!reader.get("id", id)) {
- throw std::runtime_error("Missing tile-id.");
- }
-
- bool value = false;
- if(reader.get("solid", value) && value)
- attributes |= SOLID;
- if(reader.get("unisolid", value) && value)
- attributes |= UNISOLID | SOLID;
- if(reader.get("brick", value) && value)
- attributes |= BRICK;
- if(reader.get("ice", value) && value)
- attributes |= ICE;
- if(reader.get("water", value) && value)
- attributes |= WATER;
- if(reader.get("hurts", value) && value)
- attributes |= HURTS;
- if(reader.get("fire", value) && value)
- attributes |= FIRE;
- if(reader.get("fullbox", value) && value)
- attributes |= FULLBOX;
- if(reader.get("coin", value) && value)
- attributes |= COIN;
- if(reader.get("goal", value) && value)
- attributes |= GOAL;
-
- if(reader.get("north", value) && value)
- data |= WORLDMAP_NORTH;
- if(reader.get("south", value) && value)
- data |= WORLDMAP_SOUTH;
- if(reader.get("west", value) && value)
- data |= WORLDMAP_WEST;
- if(reader.get("east", value) && value)
- data |= WORLDMAP_EAST;
- if(reader.get("stop", value) && value)
- data |= WORLDMAP_STOP;
-
- reader.get("data", data);
- reader.get("anim-fps", anim_fps);
-
- if(reader.get("slope-type", data)) {
- attributes |= SOLID | SLOPE;
- }
-
- const lisp::Lisp* images;
-#ifdef DEBUG
- images = reader.get_lisp("editor-images");
- if(images)
- parse_images(*images);
- else {
-#endif /*DEBUG*/
- images = reader.get_lisp("images");
- if(images)
- parse_images(*images);
-#ifdef DEBUG
- }
-#endif /*DEBUG*/
-
- correct_attributes();
- return id;
-}
-
-void
-Tile::parse_images(const lisp::Lisp& images_lisp)
-{
- const lisp::Lisp* list = &images_lisp;
- while(list) {
- const lisp::Lisp* cur = list->get_car();
- if(cur->get_type() == lisp::Lisp::TYPE_STRING) {
- std::string file;
- cur->get(file);
- imagespecs.push_back(ImageSpec(file, Rect(0, 0, 0, 0)));
- } else if(cur->get_type() == lisp::Lisp::TYPE_CONS &&
- cur->get_car()->get_type() == lisp::Lisp::TYPE_SYMBOL &&
- cur->get_car()->get_symbol() == "region") {
- const lisp::Lisp* ptr = cur->get_cdr();
-
- std::string file;
- float x = 0, y = 0, w = 0, h = 0;
- ptr->get_car()->get(file); ptr = ptr->get_cdr();
- ptr->get_car()->get(x); ptr = ptr->get_cdr();
- ptr->get_car()->get(y); ptr = ptr->get_cdr();
- ptr->get_car()->get(w); ptr = ptr->get_cdr();
- ptr->get_car()->get(h);
- imagespecs.push_back(ImageSpec(file, Rect(x, y, x+w, y+h)));
- } else {
- log_warning << "Expected string or list in images tag" << std::endl;
- continue;
- }
-
- list = list->get_cdr();
- }
-}
-
-void
-Tile::load_images()
-{
- const std::string& tiles_path = tileset->tiles_path;
-
- assert(images.size() == 0);
- for(std::vector<ImageSpec>::iterator i = imagespecs.begin(); i !=
- imagespecs.end(); ++i) {
- const ImageSpec& spec = *i;
- Surface* surface;
- std::string file = tiles_path + spec.file;
- if(spec.rect.get_width() <= 0) {
- surface = new Surface(file);
- } else {
- surface = new Surface(file,
- (int) spec.rect.p1.x,
- (int) spec.rect.p1.y,
- (int) spec.rect.get_width(),
- (int) spec.rect.get_height());
- }
- images.push_back(surface);
- }
-}
-
-void
-Tile::draw(DrawingContext& context, const Vector& pos, int z_pos) const
-{
- if(images.size() > 1) {
- size_t frame = size_t(game_time * anim_fps) % images.size();
- context.draw_surface(images[frame], pos, z_pos);
- } else if (images.size() == 1) {
- context.draw_surface(images[0], pos, z_pos);
- }
-}
-
-void Tile::correct_attributes()
-{
- //Fix little oddities in attributes (not many, currently...)
- if(!(attributes & SOLID) && (attributes & SLOPE || attributes & UNISOLID)) {
- attributes |= SOLID;
- //But still be vocal about it
- log_warning << "Tile with image " << imagespecs[0].file << " needs solid attribute." << std::endl;
- }
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-#ifndef TILE_H
-#define TILE_H
-
-#include <vector>
-#include <stdint.h>
-#include "video/surface.hpp"
-#include "math/rect.hpp"
-
-namespace lisp { class Lisp; }
-
-class TileSet;
-class DrawingContext;
-
-/**
-Tile Class
-*/
-class Tile
-{
-public:
- /// bitset for tile attributes
- enum {
- /** solid tile that is indestructible by Tux */
- SOLID = 0x0001,
- /** uni-directional solid tile */
- UNISOLID = 0x0002,
- /** a brick that can be destroyed by jumping under it */
- BRICK = 0x0004,
- /** the level should be finished when touching a goaltile.
- * if data is 0 then the endsequence should be triggered, if data is 1
- * then we can finish the level instantly.
- */
- GOAL = 0x0008,
- /** slope tile */
- SLOPE = 0x0010,
- /** Bonusbox, content is stored in \a data */
- FULLBOX = 0x0020,
- /** Tile is a coin */
- COIN = 0x0040,
-
- /* interesting flags (the following are passed to gameobjects) */
- FIRST_INTERESTING_FLAG = 0x0100,
-
- /** an ice brick that makes tux sliding more than usual */
- ICE = 0x0100,
- /** a water tile in which tux starts to swim */
- WATER = 0x0200,
- /** a tile that hurts the player if he touches it */
- HURTS = 0x0400,
- /** for lava: WATER, HURTS, FIRE */
- FIRE = 0x0800
- };
-
- /// worldmap flags
- enum {
- WORLDMAP_NORTH = 0x0001,
- WORLDMAP_SOUTH = 0x0002,
- WORLDMAP_EAST = 0x0004,
- WORLDMAP_WEST = 0x0008,
- WORLDMAP_DIR_MASK = 0x000f,
-
- WORLDMAP_STOP = 0x0010,
-
- // convenience values ("C" stands for crossroads)
- WORLDMAP_CNSE = WORLDMAP_NORTH | WORLDMAP_SOUTH | WORLDMAP_EAST,
- WORLDMAP_CNSW = WORLDMAP_NORTH | WORLDMAP_SOUTH | WORLDMAP_WEST,
- WORLDMAP_CNEW = WORLDMAP_NORTH | WORLDMAP_EAST | WORLDMAP_WEST,
- WORLDMAP_CSEW = WORLDMAP_SOUTH | WORLDMAP_EAST | WORLDMAP_WEST,
- WORLDMAP_CNSEW = WORLDMAP_NORTH | WORLDMAP_SOUTH | WORLDMAP_EAST | WORLDMAP_WEST
- };
-
- struct ImageSpec {
- ImageSpec(const std::string& newfile, const Rect& newrect)
- : file(newfile), rect(newrect)
- { }
-
- std::string file;
- Rect rect;
- };
-
-private:
- const TileSet *tileset;
- std::vector<ImageSpec> imagespecs;
- std::vector<Surface*> images;
-
- /// tile attributes
- uint32_t attributes;
-
- /** General purpose data attached to a tile (content of a box, type of coin)*/
- int data;
-
- float anim_fps;
-
-public:
- ~Tile();
-
- /** Draw a tile on the screen */
- void draw(DrawingContext& context, const Vector& pos, int z_pos) const;
-
- uint32_t getAttributes() const
- { return attributes; }
-
- int getData() const
- { return data; }
-
- /// returns the width of the tile in pixels
- int getWidth() const
- {
- if(!images.size())
- return 0;
- return (int) images[0]->get_width();
- }
-
- /// returns the height of the tiles in pixels
- int getHeight() const
- {
- if(!images.size())
- return 0;
- return (int) images[0]->get_height();
- }
-
-protected:
- friend class TileSet;
- Tile(const TileSet *tileset);
- Tile(const TileSet *tileset, std::vector<std::string> images, Rect rect,
- Uint32 attributes = 0, Uint32 data = 0, float animfps = 1.0);
-
- void load_images();
-
- /// parses the tile and returns it's id number
- uint32_t parse(const lisp::Lisp& reader);
- void parse_images(const lisp::Lisp& cur);
-
- //Correct small oddities in attributes that naive people
- //might miss (and rebuke them for it)
- void correct_attributes();
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-#include <config.h>
-
-#include <memory>
-#include <stdexcept>
-#include <sstream>
-#include <iostream>
-#include <limits>
-#include <assert.h>
-#include <SDL.h>
-#include "video/drawing_context.hpp"
-#include "log.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/parser.hpp"
-#include "lisp/list_iterator.hpp"
-#include "tile.hpp"
-#include "tile_set.hpp"
-#include "tile_manager.hpp"
-#include "resources.hpp"
-
-TileManager *tile_manager = NULL;
-TileSet *current_tileset = NULL;
-
-TileManager::TileManager()
-{
-}
-
-TileManager::~TileManager()
-{
-}
-
-TileSet* TileManager::get_tileset(const std::string &filename)
-{
- TileSets::const_iterator i = tilesets.find(filename);
- if(i != tilesets.end())
- return i->second;
-
- std::auto_ptr<TileSet> tileset (new TileSet(filename));
- tilesets.insert(std::make_pair(filename, tileset.get()));
-
- return tileset.release();
-}
-
-TileSet* TileManager::parse_tileset_definition(const lisp::Lisp& reader)
-{
- std::auto_ptr<TileSet> result(new TileSet());
-
- lisp::ListIterator iter(&reader);
- while(iter.next()) {
- const std::string& token = iter.item();
- if(token != "tileset") {
- log_warning << "Skipping unrecognized token \"" << token << "\" in tileset definition" << std::endl;
- continue;
- }
- const lisp::Lisp* tileset_reader = iter.lisp();
-
- std::string file;
- if (!tileset_reader->get("file", file)) {
- log_warning << "Skipping tileset import without file name" << std::endl;
- continue;
- }
-
- const TileSet *tileset = get_tileset(file);
-
- uint32_t start = 0;
- uint32_t end = std::numeric_limits<uint32_t>::max();
- uint32_t offset = 0;
- tileset_reader->get("start", start);
- tileset_reader->get("end", end);
- tileset_reader->get("offset", offset);
-
- result->merge(tileset, start, end, offset);
- }
-
- return result.release();
-}
-
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2008 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-#ifndef HEADER_TILE_MANAGER_HPP
-#define HEADER_TILE_MANAGER_HPP
-
-#include <vector>
-#include <string>
-#include <map>
-#include <iostream>
-#include <stdint.h>
-#include <assert.h>
-#include "log.hpp"
-
-namespace lisp {
-class Lisp;
-}
-
-class TileSet;
-
-class TileManager
-{
-private:
- typedef std::map<std::string, TileSet*> TileSets;
- TileSets tilesets;
-
-public:
- TileManager();
- ~TileManager();
-
- TileSet* get_tileset(const std::string &filename);
-
- TileSet* parse_tileset_definition(const lisp::Lisp& reader);
-};
-
-extern TileManager *tile_manager;
-/** this is only set while loading a map */
-extern TileSet *current_tileset;
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2008 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-#include <config.h>
-#include <stdexcept>
-
-#include "tile_set.hpp"
-#include "log.hpp"
-#include "file_system.hpp"
-#include "lisp/parser.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/list_iterator.hpp"
-
-TileSet::TileSet()
- : tiles_path(""), tiles_loaded(false)
-{
- tiles.resize(1, 0);
- tiles[0] = new Tile(this);
-}
-
-TileSet::TileSet(const std::string& filename)
- : tiles_path(""), tiles_loaded(true)
-{
- tiles_path = FileSystem::dirname(filename);
-
- tiles.resize(1, 0);
- tiles[0] = new Tile(this);
-
- lisp::Parser parser;
- const lisp::Lisp* root = parser.parse(filename);
-
- const lisp::Lisp* tiles_lisp = root->get_lisp("supertux-tiles");
- if(!tiles_lisp)
- throw std::runtime_error("file is not a supertux tiles file.");
-
- lisp::ListIterator iter(tiles_lisp);
- while(iter.next()) {
- if(iter.item() == "tile") {
- Tile* tile = new Tile(this);
- uint32_t id = tile->parse(*(iter.lisp()));
-
- if(id >= tiles.size())
- tiles.resize(id+1, 0);
-
- if(tiles[id] != 0) {
- log_warning << "Tile with ID " << id << " redefined" << std::endl;
- delete tile;
- } else {
- tiles[id] = tile;
- }
- } else if(iter.item() == "tilegroup") {
- /* tilegroups are only interesting for the editor */
- } else if (iter.item() == "tiles") {
- // List of ids (use 0 if the tile should be ignored)
- std::vector<uint32_t> ids;
- // List of attributes of the tile
- std::vector<uint32_t> attributes;
- // List of data for the tiles
- std::vector<uint32_t> datas;
- //List of frames that the tiles come in
- std::vector<std::string> images;
-
- // width and height of the image in tile units, this is used for two
- // purposes:
- // a) so we don't have to load the image here to know its dimensions
- // b) so that the resulting 'tiles' entry is more robust,
- // ie. enlarging the image won't break the tile id mapping
- // FIXME: height is actually not used, since width might be enough for
- // all purposes, still feels somewhat more natural this way
- unsigned int width = 0;
- unsigned int height = 0;
-
- iter.lisp()->get("ids", ids);
- bool has_attributes = iter.lisp()->get("attributes", attributes);
- bool has_datas = iter.lisp()->get("datas", datas);
-
- if(!iter.lisp()->get("image", images))
- iter.lisp()->get( "images", images);
-
- iter.lisp()->get("width", width);
- iter.lisp()->get("height", height);
-
- float animfps = 10;
- iter.lisp()->get("anim-fps", animfps);
-
- if(images.size() <= 0) {
- throw std::runtime_error("No images in tile.");
- }
- if(animfps < 0) {
- throw std::runtime_error("Negative fps.");
- }
- if (ids.size() != width*height) {
- std::ostringstream err;
- err << "Number of ids (" << ids.size() << ") and size of image (" << width*height
- << ") mismatch for image '" << images[0] << "', but must be equal";
- throw std::runtime_error(err.str());
- }
-
- if (has_attributes && ids.size() != attributes.size()) {
- std::ostringstream err;
- err << "Number of ids (" << ids.size() << ") and attributes (" << attributes.size()
- << ") mismatch for image '" << images[0] << "', but must be equal";
- throw std::runtime_error(err.str());
- }
-
- if (has_datas && ids.size() != datas.size()) {
- std::ostringstream err;
- err << "Number of ids (" << ids.size() << ") and datas (" << datas.size()
- << ") mismatch for image '" << images[0] << "', but must be equal";
- throw std::runtime_error(err.str());
- }
-
- for(std::vector<uint32_t>::size_type i = 0; i < ids.size() && i < width*height; ++i) {
- if (ids[i] == 0)
- continue;
-
- if(ids[i] >= tiles.size())
- tiles.resize(ids[i]+1, 0);
-
- int x = 32*(i % width);
- int y = 32*(i / width);
- Tile* tile = new Tile(this, images, Rect(x, y, x + 32, y + 32),
- (has_attributes ? attributes[i] : 0), (has_datas ? datas[i] : 0), animfps);
- if (tiles[ids[i]] == 0) {
- tiles[ids[i]] = tile;
- } else {
- log_warning << "Tile with ID " << ids[i] << " redefined" << std::endl;
- delete tile;
- }
- }
- } else if(iter.item() == "properties") {
- // deprecated
- } else {
- log_warning << "Unknown symbol '" << iter.item() << "' in tileset file" << std::endl;
- }
- }
- if (0)
- { // enable this if you want to see a list of free tiles
- log_info << "Last Tile ID is " << tiles.size()-1 << std::endl;
- int last = -1;
- for(int i = 0; i < int(tiles.size()); ++i)
- {
- if (tiles[i] == 0 && last == -1)
- {
- last = i;
- }
- else if (tiles[i] && last != -1)
- {
- log_info << "Free Tile IDs (" << i - last << "): " << last << " - " << i-1 << std::endl;
- last = -1;
- }
- }
- }
- if (0)
- { // enable this to dump the (large) list of tiles to log_debug
- // Two dumps are identical iff the tilesets specify identical tiles
- log_debug << "Tileset in " << filename << std::endl;
- for(int i = 0; i < int(tiles.size()); ++i)
- {
- if(tiles[i] == 0)
- continue;
- Tile* t = tiles[i];
- log_debug << " Tile: id " << i << ", data " << t->data << ", attributes " << t->attributes << ":" << std::endl;
- for(std::vector<Tile::ImageSpec>::iterator im = t->imagespecs.begin(); im !=
- t->imagespecs.end(); ++im) {
- log_debug << " Imagespec: file " << im->file << "; rect " << im->rect << std::endl;
- }
- }
- }
-}
-
-TileSet::~TileSet()
-{
- if(tiles_loaded) {
- for(Tiles::iterator i = tiles.begin(); i != tiles.end(); ++i)
- delete *i;
- }
-}
-
-void TileSet::merge(const TileSet *tileset, uint32_t start, uint32_t end,
- uint32_t offset)
-{
- for(uint32_t id = start; id <= end && id < tileset->tiles.size(); ++id) {
- uint32_t dest_id = id - start + offset;
-
- if(dest_id >= tiles.size())
- tiles.resize(dest_id + 1, 0);
-
- if(dest_id == 0)
- continue;
-
- Tile *tile = tileset->tiles[id];
- if(tile == NULL)
- continue;
-
- if(tiles[dest_id] != NULL) {
- log_warning << "tileset merge resulted in multiple definitions for id "
- << dest_id << "(originally " << id << ")" << std::endl;
- }
- tiles[dest_id] = tile;
- }
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2008 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-#ifndef HEADER_TILE_SET_HPP
-#define HEADER_TILE_SET_HPP
-
-#include "log.hpp"
-#include "tile.hpp"
-
-#include <vector>
-#include <string>
-
-class TileSet
-{
-private:
- typedef std::vector<Tile*> Tiles;
- Tiles tiles;
-
- std::string tiles_path;
- bool tiles_loaded;
-
- friend class TileManager;
- friend class Tile;
- TileSet(const std::string& filename);
-
-public:
- TileSet();
- ~TileSet();
-
- void merge(const TileSet *tileset, uint32_t start, uint32_t end,
- uint32_t offset);
-
- const Tile* get(uint32_t id) const
- {
- assert(id < tiles.size());
- Tile* tile = tiles[id];
- if(!tile) {
- log_warning << "Invalid tile: " << id << std::endl;
- return tiles[0];
- }
-
- if(tile->images.size() == 0 && tile->imagespecs.size() != 0)
- tile->load_images();
-
- return tile;
- }
-
- uint32_t get_max_tileid() const
- {
- return tiles.size();
- }
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-#include <config.h>
-
-#include <math.h>
-#include "timer.hpp"
-
-float game_time = 0;
-float real_time = 0;
-
-Timer::Timer()
- : period(0), cycle_start(0), cyclic(false)
-{
-}
-
-Timer::~Timer()
-{
-}
-
-void
-Timer::start(float period, bool cyclic)
-{
- this->period = period;
- this->cyclic = cyclic;
- cycle_start = game_time;
-}
-
-bool
-Timer::check()
-{
- if(period == 0)
- return false;
-
- if(game_time - cycle_start >= period) {
- if(cyclic) {
- cycle_start = game_time - fmodf(game_time - cycle_start, period);
- } else {
- period = 0;
- }
- return true;
- }
-
- return false;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-#ifndef __SUPERTUX_TIMER_H__
-#define __SUPERTUX_TIMER_H__
-
-extern float game_time;
-extern float real_time;
-
-/**
- * Simple timer designed to be used in the update functions of objects
- */
-class Timer
-{
-public:
- Timer();
- ~Timer();
-
- /** start the timer with the given period (in seconds).
- * If cyclic=true then the timer will be reset after each period.
- * Set period to zero if you want to disable the timer.
- */
- void start(float period, bool cyclic = false);
- /** returns true if a period (or more) passed since start call or last
- * successful check
- */
- bool check();
- /** stop the timer */
- void stop()
- { start(0); }
-
- /** returns the period of the timer or 0 if it isn't started */
- float get_period() const
- { return period; }
- float get_timeleft() const
- { return period - (game_time - cycle_start); }
- float get_timegone() const
- { return game_time - cycle_start; }
- bool started() const
- { return period != 0 && get_timeleft() > 0; }
-
-private:
- float period;
- float cycle_start;
- bool cyclic;
-};
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-
-#include <config.h>
-#include <version.h>
-
-#include "title.hpp"
-
-#include "addon/addon_manager.hpp"
-#include "audio/sound_manager.hpp"
-#include "fadeout.hpp"
-#include "file_system.hpp"
-#include "gameconfig.hpp"
-#include "gettext.hpp"
-#include "gui/menu.hpp"
-#include "lisp/parser.hpp"
-#include "log.hpp"
-#include "main.hpp"
-#include "mainloop.hpp"
-#include "object/camera.hpp"
-#include "object/player.hpp"
-#include "options_menu.hpp"
-#include "resources.hpp"
-#include "sector.hpp"
-#include "textscroller.hpp"
-#include "video/drawing_context.hpp"
-#include "world.hpp"
-
-#include <algorithm>
-#include <physfs.h>
-
-enum MainMenuIDs {
- MNID_STARTGAME,
- MNID_LEVELS_CONTRIB,
- MNID_ADDONS,
- MNID_OPTIONMENU,
- MNID_LEVELEDITOR,
- MNID_CREDITS,
- MNID_QUITMAINMENU
-};
-
-void
-TitleScreen::update_load_game_menu()
-{
-}
-
-void
-TitleScreen::free_contrib_menu()
-{
- for(std::vector<World*>::iterator i = contrib_worlds.begin();
- i != contrib_worlds.end(); ++i)
- delete *i;
-
- contrib_worlds.clear();
-}
-
-void
-TitleScreen::generate_contrib_menu()
-{
- /** Generating contrib levels list by making use of Level Subset */
- std::vector<std::string> level_worlds;
- char** files = PHYSFS_enumerateFiles("levels/");
- for(const char* const* filename = files; *filename != 0; ++filename) {
- std::string filepath = std::string("levels/") + *filename;
- if(PHYSFS_isDirectory(filepath.c_str()))
- level_worlds.push_back(filepath);
- }
- PHYSFS_freeList(files);
-
- free_contrib_menu();
- contrib_menu.reset(new Menu());
-
- contrib_menu->add_label(_("Contrib Levels"));
- contrib_menu->add_hl();
-
- int i = 0;
- for (std::vector<std::string>::iterator it = level_worlds.begin();
- it != level_worlds.end(); ++it) {
- try {
- std::auto_ptr<World> world (new World());
- world->load(*it + "/info");
- if(world->hide_from_contribs) {
- continue;
- }
- contrib_menu->add_entry(i++, world->title);
- contrib_worlds.push_back(world.release());
- } catch(std::exception& e) {
- log_warning << "Couldn't parse levelset info for '" << *it << "': " << e.what() << std::endl;
- }
- }
-
- contrib_menu->add_hl();
- contrib_menu->add_back(_("Back"));
-}
-
-std::string
-TitleScreen::get_level_name(const std::string& filename)
-{
- try {
- lisp::Parser parser;
- const lisp::Lisp* root = parser.parse(filename);
-
- const lisp::Lisp* level = root->get_lisp("supertux-level");
- if(!level)
- return "";
-
- std::string name;
- level->get("name", name);
- return name;
- } catch(std::exception& e) {
- log_warning << "Problem getting name of '" << filename << "': "
- << e.what() << std::endl;
- return "";
- }
-}
-
-void
-TitleScreen::check_levels_contrib_menu()
-{
- int index = contrib_menu->check();
- if (index == -1)
- return;
-
- current_world = contrib_worlds[index];
-
- if(!current_world->is_levelset) {
- start_game();
- } else {
- contrib_world_menu.reset(new Menu());
-
- contrib_world_menu->add_label(current_world->title);
- contrib_world_menu->add_hl();
-
- for (unsigned int i = 0; i < current_world->get_num_levels(); ++i)
- {
- /** get level's title */
- std::string filename = current_world->get_level_filename(i);
- std::string title = get_level_name(filename);
- contrib_world_menu->add_entry(i, title);
- }
-
- contrib_world_menu->add_hl();
- contrib_world_menu->add_back(_("Back"));
-
- Menu::push_current(contrib_world_menu.get());
- }
-}
-
-void
-TitleScreen::check_contrib_world_menu()
-{
- int index = contrib_world_menu->check();
- if (index != -1) {
- if (contrib_world_menu->get_item_by_id(index).kind == MN_ACTION) {
- sound_manager->stop_music();
- GameSession* session =
- new GameSession(current_world->get_level_filename(index));
- main_loop->push_screen(session);
- }
- }
-}
-
-namespace {
- bool generate_addons_menu_sorter(const Addon* a1, const Addon* a2)
- {
- return a1->title < a2->title;
- }
-
- const int ADDON_LIST_START_ID = 10;
-}
-
-void
-TitleScreen::generate_addons_menu()
-{
- AddonManager& adm = AddonManager::get_instance();
-
- // refresh list of addons
- addons = adm.get_addons();
-
- // sort list
- std::sort(addons.begin(), addons.end(), generate_addons_menu_sorter);
-
- // (re)generate menu
- free_addons_menu();
- addons_menu.reset(new Menu());
-
- addons_menu->add_label(_("Add-ons"));
- addons_menu->add_hl();
-
-#ifdef HAVE_LIBCURL
- addons_menu->add_entry(0, std::string(_("Check Online")));
-#else
- addons_menu->add_inactive(0, std::string(_("Check Online (disabled)")));
-#endif
-
- //addons_menu->add_hl();
-
- for (unsigned int i = 0; i < addons.size(); i++) {
- const Addon& addon = *addons[i];
- std::string text = "";
- if (addon.kind != "") text += addon.kind + " ";
- text += std::string("\"") + addon.title + "\"";
- if (addon.author != "") text += " by \"" + addon.author + "\"";
- addons_menu->add_toggle(ADDON_LIST_START_ID + i, text, addon.loaded);
- }
-
- addons_menu->add_hl();
- addons_menu->add_back(_("Back"));
-}
-
-void
-TitleScreen::check_addons_menu()
-{
- int index = addons_menu->check();
- if (index == -1) return;
-
- // check if "Check Online" was chosen
- if (index == 0) {
- try {
- AddonManager::get_instance().check_online();
- generate_addons_menu();
- Menu::set_current(addons_menu.get());
- addons_menu->set_active_item(index);
- }
- catch (std::runtime_error e) {
- log_warning << "Check for available Add-ons failed: " << e.what() << std::endl;
- }
- return;
- }
-
- // if one of the Addons listed was chosen, take appropriate action
- if ((index >= ADDON_LIST_START_ID) && (index < ADDON_LIST_START_ID) + addons.size()) {
- Addon& addon = *addons[index - ADDON_LIST_START_ID];
- if (!addon.installed) {
- try {
- AddonManager::get_instance().install(&addon);
- }
- catch (std::runtime_error e) {
- log_warning << "Installing Add-on failed: " << e.what() << std::endl;
- }
- addons_menu->set_toggled(index, addon.loaded);
- } else if (!addon.loaded) {
- try {
- AddonManager::get_instance().enable(&addon);
- }
- catch (std::runtime_error e) {
- log_warning << "Enabling Add-on failed: " << e.what() << std::endl;
- }
- addons_menu->set_toggled(index, addon.loaded);
- } else {
- try {
- AddonManager::get_instance().disable(&addon);
- }
- catch (std::runtime_error e) {
- log_warning << "Disabling Add-on failed: " << e.what() << std::endl;
- }
- addons_menu->set_toggled(index, addon.loaded);
- }
- }
-}
-
-void
-TitleScreen::free_addons_menu()
-{
-}
-
-void
-TitleScreen::make_tux_jump()
-{
- static bool jumpWasReleased = true;
- Sector* sector = titlesession->get_current_sector();
- Player* tux = sector->player;
-
- controller->update();
- controller->press(Controller::RIGHT);
-
- // Check if we should press the jump button
- Rect lookahead = tux->get_bbox();
- lookahead.p2.x += 96;
- bool pathBlocked = !sector->is_free_of_statics(lookahead);
- if ((pathBlocked && jumpWasReleased) || !tux->on_ground()) {
- controller->press(Controller::JUMP);
- jumpWasReleased = false;
- } else {
- jumpWasReleased = true;
- }
-
- // Wrap around at the end of the level back to the beginning
- if(sector->get_width() - 320 < tux->get_pos().x) {
- sector->activate("main");
- sector->camera->reset(tux->get_pos());
- }
-}
-
-TitleScreen::TitleScreen()
-{
- controller.reset(new CodeController());
- titlesession.reset(new GameSession("levels/misc/menu.stl"));
-
- Player* player = titlesession->get_current_sector()->player;
- player->set_controller(controller.get());
- player->set_speedlimit(230); //MAX_WALK_XM
-
- generate_main_menu();
-
- frame = std::auto_ptr<Surface>(new Surface("images/engine/menu/frame.png"));
-}
-
-void
-TitleScreen::generate_main_menu()
-{
- main_menu.reset(new Menu());
- main_menu->set_pos(SCREEN_WIDTH/2, SCREEN_HEIGHT/2 + 35);
- main_menu->add_entry(MNID_STARTGAME, _("Start Game"));
- main_menu->add_entry(MNID_LEVELS_CONTRIB, _("Contrib Levels"));
- main_menu->add_entry(MNID_ADDONS, _("Add-ons"));
- main_menu->add_submenu(_("Options"), get_options_menu());
- main_menu->add_entry(MNID_CREDITS, _("Credits"));
- main_menu->add_entry(MNID_QUITMAINMENU, _("Quit"));
-}
-
-TitleScreen::~TitleScreen()
-{
-}
-
-void
-TitleScreen::setup()
-{
- player_status->reset();
-
- Sector* sector = titlesession->get_current_sector();
- if(Sector::current() != sector) {
- sector->play_music(LEVEL_MUSIC);
- sector->activate(sector->player->get_pos());
- }
-
- Menu::set_current(main_menu.get());
-}
-
-void
-TitleScreen::leave()
-{
- Sector* sector = titlesession->get_current_sector();
- sector->deactivate();
- Menu::set_current(NULL);
-}
-
-void
-TitleScreen::draw(DrawingContext& context)
-{
- Sector* sector = titlesession->get_current_sector();
- sector->draw(context);
-
- // FIXME: Add something to scale the frame to the resolution of the screen
- context.draw_surface(frame.get(), Vector(0,0),LAYER_FOREGROUND1);
-
- context.draw_text(small_font, "SuperTux " PACKAGE_VERSION "\n",
- Vector(5, SCREEN_HEIGHT - 50), ALIGN_LEFT, LAYER_FOREGROUND1);
- context.draw_text(small_font,
- _(
-"Copyright (c) 2007 SuperTux Devel Team\n"
-"This game comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to\n"
-"redistribute it under certain conditions; see the file COPYING for details.\n"
-),
- Vector(5, SCREEN_HEIGHT - 50 + small_font->get_height() + 5),
- ALIGN_LEFT, LAYER_FOREGROUND1);
-}
-
-void
-TitleScreen::update(float elapsed_time)
-{
- main_loop->set_speed(0.6f);
- Sector* sector = titlesession->get_current_sector();
- sector->update(elapsed_time);
-
- make_tux_jump();
-
- Menu* menu = Menu::current();
- if(menu) {
- if(menu == main_menu.get()) {
- switch (main_menu->check()) {
- case MNID_STARTGAME:
- // Start Game, ie. goto the slots menu
- if(main_world.get() == NULL) {
- main_world.reset(new World());
- main_world->load("levels/world1/info");
- }
- current_world = main_world.get();
- start_game();
- break;
-
- case MNID_LEVELS_CONTRIB:
- // Contrib Menu
- generate_contrib_menu();
- Menu::push_current(contrib_menu.get());
- break;
-
- case MNID_ADDONS:
- // Add-ons Menu
- generate_addons_menu();
- Menu::push_current(addons_menu.get());
- break;
-
- case MNID_CREDITS:
- Menu::set_current(NULL);
- main_loop->push_screen(new TextScroller("credits.txt"),
- new FadeOut(0.5));
- break;
-
- case MNID_QUITMAINMENU:
- main_loop->quit(new FadeOut(0.25));
- sound_manager->stop_music(0.25);
- break;
- }
- } else if(menu == contrib_menu.get()) {
- check_levels_contrib_menu();
- } else if(menu == addons_menu.get()) {
- check_addons_menu();
- } else if (menu == contrib_world_menu.get()) {
- check_contrib_world_menu();
- }
- }
-
- // reopen menu if user closed it (so that the app doesn't close when user
- // accidently hit ESC)
- if(Menu::current() == 0 && main_loop->has_no_pending_fadeout()) {
- generate_main_menu();
- Menu::set_current(main_menu.get());
- }
-}
-
-void
-TitleScreen::start_game()
-{
- Menu::set_current(NULL);
- std::string basename = current_world->get_basedir();
- basename = basename.substr(0, basename.length()-1);
- std::string worlddirname = FileSystem::basename(basename);
- std::ostringstream stream;
- stream << "profile" << config->profile << "/" << worlddirname << ".stsg";
- std::string slotfile = stream.str();
-
- try {
- current_world->set_savegame_filename(slotfile);
- current_world->run();
- } catch(std::exception& e) {
- log_fatal << "Couldn't start world: " << e.what() << std::endl;
- }
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-#ifndef SUPERTUX_TITLE_H
-#define SUPERTUX_TITLE_H
-
-#include <memory>
-#include <vector>
-#include "screen.hpp"
-#include "game_session.hpp"
-#include "addon/addon.hpp"
-
-class Menu;
-class World;
-class CodeController;
-
-/**
- * Screen that displays the SuperTux logo, lets players start a new game, etc.
- */
-class TitleScreen : public Screen
-{
-public:
- TitleScreen();
- virtual ~TitleScreen();
-
- virtual void setup();
- virtual void leave();
-
- virtual void draw(DrawingContext& context);
-
- virtual void update(float elapsed_time);
-
-private:
- std::string get_level_name(const std::string& levelfile);
- void start_game();
- void make_tux_jump();
- void update_load_game_menu();
- void generate_main_menu();
- void generate_contrib_menu();
- void check_levels_contrib_menu();
- void check_contrib_world_menu();
- void free_contrib_menu();
- void generate_addons_menu();
- void check_addons_menu();
- void free_addons_menu();
-
- std::auto_ptr<Menu> main_menu;
- std::auto_ptr<Menu> contrib_menu;
- std::auto_ptr<Menu> contrib_world_menu;
- std::auto_ptr<World> main_world;
- std::vector<World*> contrib_worlds;
- std::auto_ptr<Menu> addons_menu;
- std::vector<Addon*> addons; /**< shown list of Add-ons */
- World* current_world;
-
- std::auto_ptr<Surface> frame;
- std::auto_ptr<CodeController> controller;
- std::auto_ptr<GameSession> titlesession;
-};
-
-#endif
-// $Id$
-//
// SuperTux - Climbable area
// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "climbable.hpp"
+#include "trigger/climbable.hpp"
-#include "game_session.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
-#include "main.hpp"
-#include "sector.hpp"
-#include "level.hpp"
-#include "gettext.hpp"
-#include "object/tilemap.hpp"
+#include "object/player.hpp"
+#include "supertux/main.hpp"
+#include "supertux/object_factory.hpp"
+#include "util/gettext.hpp"
+#include "util/reader.hpp"
namespace {
- const float GRACE_DX = 8; // how far off may the player's bounding-box be x-wise
- const float GRACE_DY = 8; // how far off may the player's bounding-box be y-wise
- const float ACTIVATE_TRY_FOR = 1; // how long to try correcting mis-alignment of player and climbable before giving up
- const float POSITION_FIX_AX = 50; // x-wise acceleration applied to player when trying to align player and Climbable
- const float POSITION_FIX_AY = 50; // y-wise acceleration applied to player when trying to align player and Climbable
+const float GRACE_DX = 8; // how far off may the player's bounding-box be x-wise
+const float GRACE_DY = 8; // how far off may the player's bounding-box be y-wise
+const float ACTIVATE_TRY_FOR = 1; // how long to try correcting mis-alignment of player and climbable before giving up
+const float POSITION_FIX_AX = 50; // x-wise acceleration applied to player when trying to align player and Climbable
+const float POSITION_FIX_AY = 50; // y-wise acceleration applied to player when trying to align player and Climbable
}
-Climbable::Climbable(const lisp::Lisp& reader)
+Climbable::Climbable(const Reader& reader)
: climbed_by(0)
{
reader.get("x", bbox.p1.x);
}
}
-void
-Climbable::write(lisp::Writer& writer)
-{
- writer.start_list("climbable");
-
- writer.write("x", bbox.p1.x);
- writer.write("y", bbox.p1.y);
- writer.write("width", bbox.get_width());
- writer.write("height", bbox.get_height());
-
- writer.end_list("climbable");
-}
-
void
Climbable::update(float /*elapsed_time*/)
{
IMPLEMENT_FACTORY(Climbable, "climbable");
+/* EOF */
-// $Id$
-//
// SuperTux - Climbable area
// Copyright (C) 2007 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __CLIMBABLE_H__
-#define __CLIMBABLE_H__
+#ifndef HEADER_SUPERTUX_TRIGGER_CLIMBABLE_HPP
+#define HEADER_SUPERTUX_TRIGGER_CLIMBABLE_HPP
-#include "trigger_base.hpp"
-#include "serializable.hpp"
-#include "resources.hpp"
+#include "supertux/resources.hpp"
+#include "supertux/timer.hpp"
+#include "trigger/trigger_base.hpp"
+#include "util/reader_fwd.hpp"
#include "video/drawing_context.hpp"
-#include "timer.hpp"
-#include "object/player.hpp"
-class Climbable : public TriggerBase, public Serializable
+class Player;
+
+class Climbable : public TriggerBase
{
static Color text_color;
public:
- Climbable(const lisp::Lisp& reader);
+ Climbable(const Reader& reader);
Climbable(const Rect& area);
~Climbable();
- void write(lisp::Writer& writer);
void event(Player& player, EventType type);
void update(float elapsed_time);
void draw(DrawingContext& context);
protected:
Player* climbed_by; /**< set to player who's currently climbing us, null if nobody is */
Timer activate_try_timer; /**< try to correct mis-alignment while this timer runs */
+
+private:
+ Climbable(const Climbable&);
+ Climbable& operator=(const Climbable&);
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "door.hpp"
-#include "game_session.hpp"
-#include "resources.hpp"
-#include "object_factory.hpp"
-#include "sprite/sprite.hpp"
-#include "sprite/sprite_manager.hpp"
-#include "video/drawing_context.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
#include "audio/sound_manager.hpp"
+#include "object/player.hpp"
+#include "sprite/sprite_manager.hpp"
+#include "supertux/game_session.hpp"
+#include "supertux/object_factory.hpp"
+#include "trigger/door.hpp"
-Door::Door(const lisp::Lisp& reader)
- : state(CLOSED)
+Door::Door(const Reader& reader) :
+ state(CLOSED)
{
reader.get("x", bbox.p1.x);
reader.get("y", bbox.p1.y);
sound_manager->preload("sounds/door.wav");
}
-Door::Door(int x, int y, std::string sector, std::string spawnpoint)
- : state(CLOSED)
+Door::Door(int x, int y, std::string sector, std::string spawnpoint) :
+ state(CLOSED)
{
bbox.set_pos(Vector(x, y));
target_sector = sector;
Door::~Door()
{
- delete sprite;
-}
-
-void
-Door::write(lisp::Writer& writer)
-{
- writer.start_list("door");
-
- writer.write("x", bbox.p1.x);
- writer.write("y", bbox.p1.y);
- writer.write("width", bbox.get_width());
- writer.write("height", bbox.get_height());
-
- writer.write("sector", target_sector);
- writer.write("spawnpoint", target_spawnpoint);
-
- writer.end_list("door");
}
void
if(sprite->animation_done()) {
state = OPEN;
sprite->set_action("open");
- stay_open_timer.start(1.0);
+ stay_open_timer.start(1.0);
}
break;
case OPEN:
case OPENING:
break;
case OPEN:
- {
- // if door is open and was touched by a player, teleport the player
- Player* player = dynamic_cast<Player*> (&other);
- if (player) {
- state = CLOSING;
- sprite->set_action("closing", 1);
- GameSession::current()->respawn(target_sector, target_spawnpoint);
- }
+ {
+ // if door is open and was touched by a player, teleport the player
+ Player* player = dynamic_cast<Player*> (&other);
+ if (player) {
+ state = CLOSING;
+ sprite->set_action("closing", 1);
+ GameSession::current()->respawn(target_sector, target_spawnpoint);
}
- break;
+ }
+ break;
case CLOSING:
break;
}
}
IMPLEMENT_FACTORY(Door, "door");
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#ifndef SUPERTUX_DOOR_H
-#define SUPERTUX_DOOR_H
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <string>
+#ifndef HEADER_SUPERTUX_TRIGGER_DOOR_HPP
+#define HEADER_SUPERTUX_TRIGGER_DOOR_HPP
-#include "video/surface.hpp"
#include "sprite/sprite.hpp"
-#include "trigger_base.hpp"
-#include "serializable.hpp"
-#include "timer.hpp"
-#include "object/player.hpp"
+#include "trigger/trigger_base.hpp"
+
+class Player;
-class Door : public TriggerBase, public Serializable
+class Door : public TriggerBase
{
public:
- Door(const lisp::Lisp& reader);
+ Door(const Reader& reader);
Door(int x, int y, std::string sector, std::string spawnpoint);
virtual ~Door();
- virtual void write(lisp::Writer& writer);
-
virtual void update(float elapsed_time);
virtual void draw(DrawingContext& context);
virtual void event(Player& player, EventType type);
CLOSING
};
+private:
DoorState state; /**< current state of the door */
std::string target_sector; /**< target sector to teleport to */
std::string target_spawnpoint; /**< target spawnpoint to teleport to */
- Sprite* sprite; /**< "door" sprite to render */
+ std::auto_ptr<Sprite> sprite; /**< "door" sprite to render */
Timer stay_open_timer; /**< time until door will close again */
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+#include <memory>
#include <sstream>
#include <stdexcept>
-#include <memory>
-#include "scripttrigger.hpp"
-#include "game_session.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
-#include "sector.hpp"
+#include "supertux/object_factory.hpp"
+#include "supertux/sector.hpp"
+#include "trigger/scripttrigger.hpp"
+#include "util/reader.hpp"
-ScriptTrigger::ScriptTrigger(const lisp::Lisp& reader)
+ScriptTrigger::ScriptTrigger(const Reader& reader)
{
bool must_activate = false;
}
void
-ScriptTrigger::write(lisp::Writer& writer)
-{
- writer.start_list("scripttrigger");
-
- writer.write("x", bbox.p1.x);
- writer.write("y", bbox.p1.y);
- writer.write("width", bbox.get_width());
- writer.write("height", bbox.get_height());
- writer.write("script", script);
- writer.write("button", triggerevent == EVENT_ACTIVATE);
-
- writer.end_list("scripttrigger");
-}
-
-void
ScriptTrigger::event(Player& , EventType type)
{
if(type != triggerevent)
}
IMPLEMENT_FACTORY(ScriptTrigger, "scripttrigger");
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#ifndef __SCRIPTTRIGGER_H__
-#define __SCRIPTTRIGGER_H__
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "trigger_base.hpp"
-#include "serializable.hpp"
+#ifndef HEADER_SUPERTUX_TRIGGER_SCRIPTTRIGGER_HPP
+#define HEADER_SUPERTUX_TRIGGER_SCRIPTTRIGGER_HPP
-namespace lisp {
-class Lisp;
-class Writer;
-}
+#include "trigger/trigger_base.hpp"
-class ScriptTrigger : public TriggerBase, public Serializable
+class ScriptTrigger : public TriggerBase
{
public:
- ScriptTrigger(const lisp::Lisp& reader);
+ ScriptTrigger(const Reader& reader);
ScriptTrigger(const Vector& pos, const std::string& script);
~ScriptTrigger();
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "secretarea_trigger.hpp"
+#include "trigger/secretarea_trigger.hpp"
-#include "resources.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
-#include "main.hpp"
-#include "sector.hpp"
-#include "level.hpp"
-#include "gettext.hpp"
#include "object/tilemap.hpp"
+#include "supertux/level.hpp"
+#include "supertux/main.hpp"
+#include "supertux/object_factory.hpp"
+#include "supertux/resources.hpp"
+#include "supertux/sector.hpp"
+#include "util/gettext.hpp"
+#include "util/reader.hpp"
+#include "util/writer.hpp"
static const float MESSAGE_TIME=3.5;
-SecretAreaTrigger::SecretAreaTrigger(const lisp::Lisp& reader)
- : fade_tilemap("")
+SecretAreaTrigger::SecretAreaTrigger(const Reader& reader) :
+ fade_tilemap("")
{
reader.get("x", bbox.p1.x);
reader.get("y", bbox.p1.y);
}
SecretAreaTrigger::SecretAreaTrigger(const Rect& area, std::string fade_tilemap)
- : fade_tilemap(fade_tilemap)
+ : fade_tilemap(fade_tilemap)
{
bbox = area;
message_displayed = false;
}
void
-SecretAreaTrigger::write(lisp::Writer& writer)
-{
- writer.start_list("secretarea");
-
- writer.write("x", bbox.p1.x);
- writer.write("y", bbox.p1.y);
- writer.write("width", bbox.get_width());
- writer.write("height", bbox.get_height());
- writer.write("fade-tilemap", fade_tilemap);
-
- writer.end_list("secretarea");
-}
-
-void
SecretAreaTrigger::draw(DrawingContext& context)
{
if (message_timer.started()) {
}
IMPLEMENT_FACTORY(SecretAreaTrigger, "secretarea");
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __SECRETAREA_TRIGGER_H__
-#define __SECRETAREA_TRIGGER_H__
+#ifndef HEADER_SUPERTUX_TRIGGER_SECRETAREA_TRIGGER_HPP
+#define HEADER_SUPERTUX_TRIGGER_SECRETAREA_TRIGGER_HPP
-#include "trigger_base.hpp"
+#include "trigger/trigger_base.hpp"
-#include "serializable.hpp"
-#include "timer.hpp"
+#include "supertux/timer.hpp"
+#include "util/reader_fwd.hpp"
+#include "util/writer_fwd.hpp"
-namespace lisp {
-class Lisp;
-class Writer;
-}
class DrawingContext;
class Color;
-class SecretAreaTrigger : public TriggerBase, public Serializable
+class SecretAreaTrigger : public TriggerBase
{
static Color text_color;
public:
- SecretAreaTrigger(const lisp::Lisp& reader);
+ SecretAreaTrigger(const Reader& reader);
SecretAreaTrigger(const Rect& area, std::string fade_tilemap = "");
~SecretAreaTrigger();
- void write(lisp::Writer& writer);
void event(Player& player, EventType type);
void draw(DrawingContext& context);
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "sequence_trigger.hpp"
-#include "game_session.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-#include "object_factory.hpp"
+#include "object/player.hpp"
+#include "supertux/object_factory.hpp"
+#include "trigger/sequence_trigger.hpp"
+#include "util/reader.hpp"
-SequenceTrigger::SequenceTrigger(const lisp::Lisp& reader)
+SequenceTrigger::SequenceTrigger(const Reader& reader)
{
reader.get("x", bbox.p1.x);
reader.get("y", bbox.p1.y);
}
void
-SequenceTrigger::write(lisp::Writer& writer)
-{
- writer.start_list("sequencetrigger");
-
- writer.write("x", bbox.p1.x);
- writer.write("y", bbox.p1.y);
- writer.write("width", bbox.get_width());
- writer.write("height", bbox.get_height());
- writer.write("sequence", sequence_name);
-
- writer.end_list("sequencetrigger");
-}
-
-void
SequenceTrigger::event(Player& player, EventType type)
{
if(type == triggerevent) {
}
}
-IMPLEMENT_FACTORY(SequenceTrigger, "sequencetrigger")
+IMPLEMENT_FACTORY(SequenceTrigger, "sequencetrigger");
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+#ifndef HEADER_SUPERTUX_TRIGGER_SEQUENCE_TRIGGER_HPP
+#define HEADER_SUPERTUX_TRIGGER_SEQUENCE_TRIGGER_HPP
-#ifndef __SEQUENCE_TRIGGER_H__
-#define __SEQUENCE_TRIGGER_H__
+#include "trigger/trigger_base.hpp"
-#include "trigger_base.hpp"
-#include "serializable.hpp"
-#include "object/player.hpp"
+class Player;
-class SequenceTrigger : public TriggerBase, public Serializable
+class SequenceTrigger : public TriggerBase
{
public:
- SequenceTrigger(const lisp::Lisp& reader);
+ SequenceTrigger(const Reader& reader);
SequenceTrigger(const Vector& pos, const std::string& sequence);
~SequenceTrigger();
- void write(lisp::Writer& writer);
void event(Player& player, EventType type);
std::string get_sequence_name() const { return sequence_name; }
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux - Switch Trigger
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <config.h>
#include <stdexcept>
-#include "switch.hpp"
-#include "object_factory.hpp"
+#include "audio/sound_manager.hpp"
#include "sprite/sprite.hpp"
#include "sprite/sprite_manager.hpp"
-#include "sector.hpp"
-#include "audio/sound_manager.hpp"
+#include "supertux/object_factory.hpp"
+#include "supertux/sector.hpp"
+#include "trigger/switch.hpp"
namespace {
- const std::string SWITCH_SOUND = "sounds/switch.ogg";
+const std::string SWITCH_SOUND = "sounds/switch.ogg";
}
-Switch::Switch(const lisp::Lisp& reader)
- : state(OFF)
+Switch::Switch(const Reader& reader) :
+ state(OFF)
{
if (!reader.get("x", bbox.p1.x)) throw std::runtime_error("no x position set");
if (!reader.get("y", bbox.p1.y)) throw std::runtime_error("no y position set");
Switch::~Switch()
{
- delete sprite;
-}
-
-void
-Switch::write(lisp::Writer& writer)
-{
- writer.start_list("switch");
- writer.write("x", bbox.p1.x);
- writer.write("y", bbox.p1.y);
- writer.write("sprite", sprite_name);
- writer.write("script", script);
- writer.end_list("switch");
}
void
break;
case TURN_ON:
if(sprite->animation_done()) {
- std::istringstream stream(script);
- std::ostringstream location;
- location << "switch" << bbox.p1;
- Sector::current()->run_script(stream, location.str());
+ std::istringstream stream(script);
+ std::ostringstream location;
+ location << "switch" << bbox.p1;
+ Sector::current()->run_script(stream, location.str());
- sprite->set_action("on", 1);
- state = ON;
+ sprite->set_action("on", 1);
+ state = ON;
}
break;
case ON:
if(sprite->animation_done()) {
- sprite->set_action("turnoff", 1);
- state = TURN_OFF;
+ sprite->set_action("turnoff", 1);
+ state = TURN_OFF;
}
break;
case TURN_OFF:
if(sprite->animation_done()) {
- sprite->set_action("off");
- state = OFF;
+ sprite->set_action("off");
+ state = OFF;
}
break;
}
switch (state) {
case OFF:
- sprite->set_action("turnon", 1);
- sound_manager->play( SWITCH_SOUND );
- state = TURN_ON;
+ sprite->set_action("turnon", 1);
+ sound_manager->play( SWITCH_SOUND );
+ state = TURN_ON;
break;
case TURN_ON:
break;
}
IMPLEMENT_FACTORY(Switch, "switch");
+
+/* EOF */
-// $Id$
-//
// SuperTux - Switch Trigger
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef SUPERTUX_SWITCH_H
-#define SUPERTUX_SWITCH_H
+#ifndef HEADER_SUPERTUX_TRIGGER_SWITCH_HPP
+#define HEADER_SUPERTUX_TRIGGER_SWITCH_HPP
#include <string>
-#include "trigger_base.hpp"
-#include "serializable.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/writer.hpp"
-#include "video/drawing_context.hpp"
#include "sprite/sprite.hpp"
+#include "trigger/trigger_base.hpp"
+#include "util/reader.hpp"
+#include "video/drawing_context.hpp"
-class Switch : public TriggerBase, public Serializable
+class Switch : public TriggerBase
{
public:
- Switch(const lisp::Lisp& reader);
+ Switch(const Reader& reader);
virtual ~Switch();
- virtual void write(lisp::Writer& writer);
-
virtual void update(float elapsed_time);
virtual void draw(DrawingContext& context);
virtual void event(Player& player, EventType type);
};
std::string sprite_name;
- Sprite* sprite;
+ std::auto_ptr<Sprite> sprite;
std::string script;
SwitchState state;
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "trigger_base.hpp"
+#include "trigger/trigger_base.hpp"
-#include "sprite/sprite.hpp"
-#include "video/drawing_request.hpp"
#include "object/player.hpp"
+#include "sprite/sprite.hpp"
-TriggerBase::TriggerBase()
- : sprite(0), lasthit(false), hit(false)
+TriggerBase::TriggerBase() :
+ sprite(),
+ lasthit(false),
+ hit(false)
{
set_group(COLGROUP_TOUCHABLE);
}
void
TriggerBase::draw(DrawingContext& context)
{
- if(!sprite)
+ if(!sprite.get())
return;
sprite->draw(context, get_pos(), LAYER_TILES+1);
}
}
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef SUPERTUX_TRIGGER_BASE_H
-#define SUPERTUX_TRIGGER_BASE_H
+#ifndef HEADER_SUPERTUX_TRIGGER_TRIGGER_BASE_HPP
+#define HEADER_SUPERTUX_TRIGGER_TRIGGER_BASE_HPP
#include <list>
-#include "moving_object.hpp"
-#include "object_remove_listener.hpp"
+#include <memory>
+
+#include "supertux/moving_object.hpp"
+#include "supertux/object_remove_listener.hpp"
class Player;
class Sprite;
/** This class is the base class for all objects you can interact with in some
* way. There are several interaction types defined like touch and activate
*/
-class TriggerBase : public MovingObject, public ObjectRemoveListener
+class TriggerBase : public MovingObject,
+ public ObjectRemoveListener
{
public:
enum EventType {
virtual void object_removed(GameObject* object);
private:
- Sprite* sprite;
+ std::auto_ptr<Sprite> sprite;
bool lasthit;
bool hit;
std::list<Player*> losetouch_listeners; /**< Players that will be informed when we lose touch with them */
+
+private:
+ TriggerBase(const TriggerBase&);
+ TriggerBase& operator=(const TriggerBase&);
};
#endif /*SUPERTUX_INTERACTIVE_OBJECT_H*/
+
+/* EOF */
--- /dev/null
+/*
+** Windstille - A Sci-Fi Action-Adventure Game
+** Copyright (C) 2009 Ingo Ruhnke <grumbel@gmx.de>
+**
+** 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef HEADER_WINDSTILLE_UTIL_CURRENTON_HPP
+#define HEADER_WINDSTILLE_UTIL_CURRENTON_HPP
+
+#include <assert.h>
+
+/**
+ * A 'Currenton' allows access to the currently active instance of a
+ * class via the static current() function. It is kind of like a
+ * singleton, but without handling the object construction itself or
+ * in other words its a glorified global variable that points to the
+ * current instance of a class.
+ */
+template<class C>
+class Currenton
+{
+private:
+ static C* s_current;
+
+protected:
+ Currenton()
+ {
+ // FIXME: temporarly disabled, as Sector() for the main menu,
+ // doesn't get cleaned up before a real Sector() starts
+ // assert(!s_current);
+ s_current = static_cast<C*>(this);
+ }
+
+ virtual ~Currenton()
+ {
+ s_current = 0;
+ }
+
+public:
+ static C* current() { return s_current; }
+};
+
+template<class C> C* Currenton<C>::s_current = 0;
+
+#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include "util/log.hpp"
+
+#include <sstream>
+#include <vector>
+
+namespace FileSystem {
+
+std::string dirname(const std::string& filename)
+{
+ std::string::size_type p = filename.find_last_of('/');
+ if(p == std::string::npos)
+ p = filename.find_last_of('\\');
+ if(p == std::string::npos)
+ return "./";
+
+ return filename.substr(0, p+1);
+}
+
+std::string basename(const std::string& filename)
+{
+ std::string::size_type p = filename.find_last_of('/');
+ if(p == std::string::npos)
+ p = filename.find_last_of('\\');
+ if(p == std::string::npos)
+ return filename;
+
+ return filename.substr(p+1, filename.size()-p-1);
+}
+
+std::string strip_extension(const std::string& filename)
+{
+ std::string::size_type p = filename.find_last_of('.');
+ if(p == std::string::npos)
+ return filename;
+
+ return filename.substr(0, p);
+}
+
+std::string normalize(const std::string& filename)
+{
+ std::vector<std::string> path_stack;
+
+ const char* p = filename.c_str();
+
+ while(true) {
+ while(*p == '/' || *p == '\\') {
+ p++;
+ continue;
+ }
+
+ const char* pstart = p;
+ while(*p != '/' && *p != '\\' && *p != 0) {
+ ++p;
+ }
+
+ size_t len = p - pstart;
+ if(len == 0)
+ break;
+
+ std::string pathelem(pstart, p-pstart);
+ if(pathelem == ".")
+ continue;
+
+ if(pathelem == "..") {
+ if(path_stack.empty()) {
+
+ log_warning << "Invalid '..' in path '" << filename << "'" << std::endl;
+ // push it into the result path so that the user sees his error...
+ path_stack.push_back(pathelem);
+ } else {
+ path_stack.pop_back();
+ }
+ } else {
+ path_stack.push_back(pathelem);
+ }
+ }
+
+ // construct path
+ std::ostringstream result;
+ for(std::vector<std::string>::iterator i = path_stack.begin();
+ i != path_stack.end(); ++i) {
+ result << '/' << *i;
+ }
+ if(path_stack.empty())
+ result << '/';
+
+ return result.str();
+}
+
+} // namespace FileSystem
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_UTIL_FILE_SYSTEM_HPP
+#define HEADER_SUPERTUX_UTIL_FILE_SYSTEM_HPP
+
+namespace FileSystem {
+
+/**
+ * returns the path of the directory the file is in
+ */
+std::string dirname(const std::string& filename);
+
+/**
+ * returns the name of the file
+ */
+std::string basename(const std::string& filename);
+
+/**
+ * remove everything starting from and including the last dot
+ */
+std::string strip_extension(const std::string& filename);
+
+/**
+ * normalize filename so that "blup/bla/blo/../../bar" will become
+ * "blup/bar"
+ */
+std::string normalize(const std::string& filename);
+
+} // namespace FileSystem
+
+#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Ingo Ruhnke <grumbel@gmx.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_UTIL_GETTEXT_HPP
+#define HEADER_SUPERTUX_UTIL_GETTEXT_HPP
+
+#include "tinygettext/tinygettext.hpp"
+
+extern TinyGetText::DictionaryManager dictionary_manager;
+
+static inline const char* _(const char* message)
+{
+ return dictionary_manager.get_dictionary().translate(message);
+}
+
+static inline std::string _(const std::string& message)
+{
+ return dictionary_manager.get_dictionary().translate(message);
+}
+
+static inline const char* N_(const char* id, const char* id2, int num)
+{
+ return dictionary_manager.get_dictionary().translate(id, id2, num).c_str();
+}
+
+#endif /* _LIBGETTEXT_H */
+
+/* EOF */
--- /dev/null
+// SuperTux Debug Helper Functions
+// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include "util/log.hpp"
+
+#include "math/rect.hpp"
+#include "supertux/console.hpp"
+
+#ifdef DEBUG
+
+std::ostream& log_debug_f(const char* file, int line)
+{
+ Console::output << "[DEBUG] " << file << ":" << line << " ";
+ return Console::output;
+}
+
+std::ostream& log_info_f(const char* file, int line)
+{
+ Console::output << "[INFO] " << file << ":" << line << " ";
+ return Console::output;
+}
+
+std::ostream& log_warning_f(const char* file, int line)
+{
+ Console::output << "[WARNING] " << file << ":" << line << " ";
+ return Console::output;
+}
+
+std::ostream& log_fatal_f(const char* file, int line)
+{
+ Console::output << "[FATAL] " << file << ":" << line << " ";
+ return Console::output;
+}
+
+#else
+
+std::ostream& log_fatal_f()
+{
+ Console::output << "Fatal: ";
+ return Console::output;
+}
+
+#endif
+
+std::ostream& operator<<(std::ostream& out, const Vector& vector)
+{
+ out << '[' << vector.x << ',' << vector.y << ']';
+ return out;
+}
+
+std::ostream& operator<<(std::ostream& out, const Rect& rect)
+{
+ out << "[" << rect.get_left() << "," << rect.get_top() << " "
+ << rect.get_right() << "," << rect.get_bottom() << "]";
+ return out;
+}
+
+/* EOF */
--- /dev/null
+// SuperTux Debug Helper Functions
+// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_UTIL_LOG_HPP
+#define HEADER_SUPERTUX_UTIL_LOG_HPP
+
+#include <config.h>
+
+#ifdef DEBUG
+
+#include <ostream>
+
+std::ostream& log_debug_f(const char* file, int line);
+std::ostream& log_info_f(const char* file, int line);
+std::ostream& log_warning_f(const char* file, int line);
+std::ostream& log_fatal_f(const char* file, int line);
+
+#define log_debug log_debug_f(__FILE__, __LINE__)
+#define log_info log_info_f(__FILE__, __LINE__)
+#define log_warning log_warning_f(__FILE__, __LINE__)
+#define log_fatal log_fatal_f(__FILE__, __LINE__)
+
+#else
+
+#include <iostream>
+
+std::ostream& log_fatal_f();
+
+#define log_debug if (0) std::cerr
+#define log_info std::cout
+#define log_warning std::cerr
+#define log_fatal log_fatal_f()
+
+#endif
+
+class Vector;
+std::ostream& operator<< (std::ostream& str, const Vector& vector);
+class Rect;
+std::ostream& operator<< (std::ostream& str, const Rect& rect);
+
+#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2009 Ingo Ruhnke <grumbel@gmx.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_UTIL_READER_HPP
+#define HEADER_SUPERTUX_UTIL_READER_HPP
+
+#include "lisp/lisp.hpp"
+
+typedef lisp::Lisp Reader;
+
+#endif
+
+/* EOF */
+
--- /dev/null
+// SuperTux
+// Copyright (C) 2009 Ingo Ruhnke <grumbel@gmx.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_UTIL_READER_FWD_HPP
+#define HEADER_SUPERTUX_UTIL_READER_FWD_HPP
+
+namespace lisp {
+class Lisp;
+} // namespace lisp
+
+typedef lisp::Lisp Reader;
+
+#endif
+
+/* EOF */
+
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_UTIL_REF_HPP
+#define HEADER_SUPERTUX_UTIL_REF_HPP
+
+/** This class behaves like a pointer to a refcounted object, but increments the
+ * reference count when new objects are assigned and decrements the refcounter
+ * when its lifetime has expired. (similar to std::auto_ptr)
+ */
+template<typename T>
+class Ref
+{
+public:
+ Ref(T* object = 0)
+ : object(object)
+ {
+ if(object)
+ object->ref();
+ }
+ Ref(const Ref<T>& other)
+ : object(other.object)
+ {
+ if(object)
+ object->ref();
+ }
+ ~Ref()
+ {
+ if(object)
+ object->unref();
+ }
+
+ Ref<T>& operator= (const Ref<T>& other)
+ {
+ *this = other.get();
+ return *this;
+ }
+
+ Ref<T>& operator= (T* object)
+ {
+ if(object)
+ object->ref();
+ if(this->object)
+ this->object->unref();
+ this->object = object;
+
+ return *this;
+ }
+
+ T* operator ->() const
+ {
+ return object;
+ }
+
+ T& operator* () const
+ {
+ return *object;
+ }
+
+ operator const T* () const
+ {
+ return object;
+ }
+
+ T* get() const
+ {
+ return object;
+ }
+
+private:
+ T* object;
+};
+
+#endif
+
+/* EOF */
--- /dev/null
+// Windstille - A Jump'n Shoot Game
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_UTIL_REFCOUNTER_HPP
+#define HEADER_SUPERTUX_UTIL_REFCOUNTER_HPP
+
+#include <assert.h>
+
+/**
+ * A base class that provides reference counting facilities
+ */
+class RefCounter
+{
+public:
+ RefCounter()
+ : refcount(0)
+ { }
+
+ /** increases reference count */
+ void ref()
+ {
+ refcount++;
+ }
+ /** decreases reference count. Destroys the object if the reference count
+ * reaches 0
+ */
+ void unref()
+ {
+ refcount--;
+ if(refcount <= 0) {
+ delete this;
+ }
+ }
+
+protected:
+ virtual ~RefCounter()
+ {
+ assert(refcount == 0);
+ }
+
+private:
+ int refcount;
+};
+
+#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2009 Ingo Ruhnke <grumbel@gmx.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_UTIL_WRITER_HPP
+#define HEADER_SUPERTUX_UTIL_WRITER_HPP
+
+#include "lisp/writer.hpp"
+
+typedef lisp::Writer Writer;
+
+#endif
+
+/* EOF */
+
--- /dev/null
+// SuperTux
+// Copyright (C) 2009 Ingo Ruhnke <grumbel@gmx.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_UTIL_WRITER_FWD_HPP
+#define HEADER_SUPERTUX_UTIL_WRITER_FWD_HPP
+
+namespace lisp {
+class Writer;
+} // namespace lisp
+
+typedef lisp::Writer Writer;
+
+#endif
+
+/* EOF */
+
-// $Id: color.cpp 5063 2007-05-27 11:32:00Z matzeb $
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
#include <config.h>
-#include "color.hpp"
+#include "video/color.hpp"
const Color Color::BLACK(0.0, 0.0, 0.0);
const Color Color::RED(1.0, 0.0, 0.0);
const Color Color::MAGENTA(1.0, 0.0, 1.0);
const Color Color::YELLOW(1.0, 1.0, 0.0);
const Color Color::WHITE(1.0, 1.0, 1.0);
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __COLOR_HPP__
-#define __COLOR_HPP__
+#ifndef HEADER_SUPERTUX_VIDEO_COLOR_HPP
+#define HEADER_SUPERTUX_VIDEO_COLOR_HPP
-#include <vector>
#include <assert.h>
-#include "log.hpp"
+#include <vector>
+
+#include "util/log.hpp"
class Color
{
public:
- Color()
- : red(0), green(0), blue(0), alpha(1.0)
- { }
- Color(float red, float green, float blue, float alpha = 1.0)
- : red(red), green(green), blue(blue), alpha(alpha)
+ Color() :
+ red(0),
+ green(0),
+ blue(0),
+ alpha(1.0f)
+ {}
+
+ Color(float red, float green, float blue, float alpha = 1.0) :
+ red(red),
+ green(green),
+ blue(blue),
+ alpha(alpha)
{
#ifdef DEBUG
check_color_ranges();
#endif
}
- Color(const std::vector<float>& vals)
+
+ Color(const std::vector<float>& vals) :
+ red(),
+ green(),
+ blue(),
+ alpha()
{
assert(vals.size() >= 3);
- red = vals[0];
+ red = vals[0];
green = vals[1];
- blue = vals[2];
+ blue = vals[2];
if(vals.size() > 3)
alpha = vals[3];
else
bool operator==(const Color& other) const
{
return red == other.red && green == other.green && blue == other.blue
- && alpha == other.alpha;
+ && alpha == other.alpha;
}
void check_color_ranges()
{
if(red < 0 || red > 1.0 || green < 0 || green > 1.0
- || blue < 0 || blue > 1.0
- || alpha < 0 || alpha > 1.0)
+ || blue < 0 || blue > 1.0
+ || alpha < 0 || alpha > 1.0)
log_warning << "color value out of range: " << red << ", " << green << ", " << blue << ", " << alpha << std::endl;
}
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
#include <algorithm>
+#include <config.h>
+
+#include "video/drawing_context.hpp"
-#include "drawing_context.hpp"
-
-#include "drawing_request.hpp"
-#include "video_systems.hpp"
-#include "renderer.hpp"
-#include "lightmap.hpp"
-#include "surface.hpp"
-#include "main.hpp"
-#include "gameconfig.hpp"
-#include "texture.hpp"
-#include "texture_manager.hpp"
#include "obstack/obstackpp.hpp"
+#include "supertux/gameconfig.hpp"
+#include "supertux/main.hpp"
+#include "video/drawing_request.hpp"
+#include "video/lightmap.hpp"
+#include "video/renderer.hpp"
+#include "video/surface.hpp"
+#include "video/texture.hpp"
+#include "video/texture_manager.hpp"
+#include "video/video_systems.hpp"
static inline int next_po2(int val)
{
request->pos = transform.apply(position);
if(request->pos.x >= SCREEN_WIDTH || request->pos.y >= SCREEN_HEIGHT
- || request->pos.x + surface->get_width() < 0
- || request->pos.y + surface->get_height() < 0)
+ || request->pos.x + surface->get_width() < 0
+ || request->pos.y + surface->get_height() < 0)
return;
request->layer = layer;
void
DrawingContext::draw_surface(const Surface* surface, const Vector& position,
- int layer)
+ int layer)
{
draw_surface(surface, position, 0.0f, Color(1.0f, 1.0f, 1.0f), Blend(), layer);
}
void
DrawingContext::draw_surface_part(const Surface* surface, const Vector& source,
- const Vector& size, const Vector& dest, int layer)
+ const Vector& size, const Vector& dest, int layer)
{
assert(surface != 0);
void
DrawingContext::draw_text(const Font* font, const std::string& text,
- const Vector& position, FontAlignment alignment, int layer, Color color)
+ const Vector& position, FontAlignment alignment, int layer, Color color)
{
DrawingRequest* request = new(obst) DrawingRequest();
void
DrawingContext::draw_center_text(const Font* font, const std::string& text,
- const Vector& position, int layer, Color color)
+ const Vector& position, int layer, Color color)
{
draw_text(font, text, Vector(position.x + SCREEN_WIDTH/2, position.y),
- ALIGN_CENTER, layer, color);
+ ALIGN_CENTER, layer, color);
}
void
//There is no light offscreen.
if(request->pos.x >= SCREEN_WIDTH || request->pos.y >= SCREEN_HEIGHT
- || request->pos.x < 0 || request->pos.y < 0){
+ || request->pos.x < 0 || request->pos.y < 0){
*color = Color( 0, 0, 0);
return;
}
renderer->draw_gradient(request);
break;
case TEXT:
- {
- const TextRequest* textrequest = (TextRequest*) request.request_data;
- textrequest->font->draw(renderer, textrequest->text, request.pos,
- textrequest->alignment, request.drawing_effect, request.color, request.alpha);
- }
- break;
+ {
+ const TextRequest* textrequest = (TextRequest*) request.request_data;
+ textrequest->font->draw(renderer, textrequest->text, request.pos,
+ textrequest->alignment, request.drawing_effect, request.color, request.alpha);
+ }
+ break;
case FILLRECT:
renderer->draw_filled_rect(request);
break;
lightmap->draw_gradient(request);
break;
case TEXT:
- {
- const TextRequest* textrequest = (TextRequest*) request.request_data;
- textrequest->font->draw(renderer, textrequest->text, request.pos,
- textrequest->alignment, request.drawing_effect, request.color, request.alpha);
- }
- break;
+ {
+ const TextRequest* textrequest = (TextRequest*) request.request_data;
+ textrequest->font->draw(renderer, textrequest->text, request.pos,
+ textrequest->alignment, request.drawing_effect, request.color, request.alpha);
+ }
+ break;
case FILLRECT:
lightmap->draw_filled_rect(request);
break;
screenshot_requested = true;
}
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#ifndef SUPERTUX_DRAWINGCONTEXT_H
-#define SUPERTUX_DRAWINGCONTEXT_H
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_VIDEO_DRAWING_CONTEXT_HPP
+#define HEADER_SUPERTUX_VIDEO_DRAWING_CONTEXT_HPP
-#include <vector>
-#include <string>
#include <memory>
+#include <string>
+#include <vector>
#include <stdint.h>
-#include "obstack/obstack.h"
-#include "math/vector.hpp"
#include "math/rect.hpp"
-#include "color.hpp"
-#include "font.hpp"
-#include "drawing_request.hpp"
+#include "math/vector.hpp"
+#include "obstack/obstack.h"
+#include "video/color.hpp"
+#include "video/drawing_request.hpp"
+#include "video/font.hpp"
+#include "video/texture.hpp"
class Surface;
class Texture;
DrawingEffect drawing_effect;
float alpha;
- Transform()
- : drawing_effect(NO_EFFECT), alpha(1.0f)
+ Transform() :
+ translation(),
+ drawing_effect(NO_EFFECT),
+ alpha(1.0f)
{ }
Vector apply(const Vector& v) const
struct obstack obst;
bool screenshot_requested; /**< true if a screenshot should be taken after the next frame has been rendered */
+
+private:
+ DrawingContext(const DrawingContext&);
+ DrawingContext& operator=(const DrawingContext&);
};
#endif
+/* EOF */
-// $Id: drawing_request.hpp 4986 2007-04-16 17:48:28Z matzeb $
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#ifndef SUPERTUX_DRAWINGREQUEST_H
-#define SUPERTUX_DRAWINGREQUEST_H
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_VIDEO_DRAWING_REQUEST_HPP
+#define HEADER_SUPERTUX_VIDEO_DRAWING_REQUEST_HPP
-#include <vector>
-#include <string>
#include <memory>
+#include <string>
+#include <vector>
#include <stdint.h>
-#include "glutil.hpp"
-#include "color.hpp"
-#include "font.hpp"
#include "math/vector.hpp"
+#include "video/color.hpp"
+#include "video/font.hpp"
+#include "video/glutil.hpp"
class Surface;
void* request_data;
- DrawingRequest()
- : angle(0.0f),
- color(1.0f, 1.0f, 1.0f, 1.0f)
+ DrawingRequest() :
+ target(),
+ type(),
+ pos(),
+ layer(),
+ drawing_effect(),
+ alpha(),
+ blend(),
+ angle(0.0f),
+ color(1.0f, 1.0f, 1.0f, 1.0f),
+ request_data()
{}
bool operator<(const DrawingRequest& other) const
#endif
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
// Ingo Ruhnke <grumbel@gmx.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <config.h>
#include <cstdlib>
#include <cstring>
#include <stdexcept>
-
#include <SDL_image.h>
-#include "physfs/physfs_sdl.hpp"
#include <physfs.h>
-#include "file_system.hpp"
+
+#include "physfs/physfs_sdl.hpp"
+
+#include "util/file_system.hpp"
#include "lisp/lisp.hpp"
-#include "lisp/parser.hpp"
#include "lisp/list_iterator.hpp"
-#include "screen.hpp"
-#include "font.hpp"
-#include "renderer.hpp"
-#include "drawing_context.hpp"
-#include "log.hpp"
+#include "lisp/parser.hpp"
+#include "supertux/screen.hpp"
+#include "util/log.hpp"
+#include "video/drawing_context.hpp"
+#include "video/font.hpp"
+#include "video/renderer.hpp"
namespace {
bool has_multibyte_mark(unsigned char c);
std::string::size_type pos;
uint32_t chr;
- UTF8Iterator(const std::string& text_)
- : text(text_),
- pos(0)
+ UTF8Iterator(const std::string& text_) :
+ text(text_),
+ pos(0),
+ chr()
{
try {
chr = decode_utf8(text, pos);
Uint8* pixels = (Uint8*)surface->pixels;
for(int y = start_y; y < end_y; ++y)
+ {
+ const Uint8& p = pixels[surface->pitch*y + x*surface->format->BytesPerPixel + 3];
+ if (p > threshold)
{
- const Uint8& p = pixels[surface->pitch*y + x*surface->format->BytesPerPixel + 3];
- if (p > threshold)
- {
- return false;
- }
+ return false;
}
+ }
return true;
}
} // namespace
Font::Font(GlyphWidth glyph_width_,
const std::string& filename,
int shadowsize_)
-: glyph_width(glyph_width_),
- shadowsize(shadowsize_),
- glyphs(65536)
+ : glyph_width(glyph_width_),
+ shadowsize(shadowsize_),
+ glyphs(65536)
{
for(unsigned int i=0; i<65536;i++) glyphs[i].surface_idx = -1;
std::string filename(*i);
if( filename.rfind(fontname) != std::string::npos ) {
loadFontFile(fontdir + filename);
- }
}
+ }
PHYSFS_freeList(rc);
}
std::ostringstream msg;
msg << "Font file:" << filename << ": is not a supertux-font file";
throw std::runtime_error(msg.str());
- }
+ }
int def_char_width=0;
if( !config_l->get("glyph-width",def_char_width) ) {
log_warning << "Font:"<< filename << ": misses default glyph-width" << std::endl;
- }
+ }
if( !config_l->get("glyph-height",char_height) ) {
std::ostringstream msg;
msg << "Font:" << filename << ": misses glyph-height";
throw std::runtime_error(msg.str());
- }
+ }
lisp::ListIterator iter(config_l);
while(iter.next()) {
std::vector<std::string> chars;
if( ! glyphs_val->get("glyph-width", local_char_width) ) {
local_char_width = def_char_width;
- }
+ }
if( ! glyphs_val->get("monospace", monospaced ) ) {
local_glyph_width = glyph_width;
- }
+ }
else {
if( monospaced ) local_glyph_width = FIXED;
else local_glyph_width = VARIABLE;
- }
+ }
if( ! glyphs_val->get("glyphs", glyph_image) ) {
std::ostringstream msg;
msg << "Font:" << filename << ": missing glyphs image";
throw std::runtime_error(msg.str());
- }
+ }
if( ! glyphs_val->get("shadows", shadow_image) ) {
std::ostringstream msg;
msg << "Font:" << filename << ": missing shadows image";
throw std::runtime_error(msg.str());
- }
+ }
if( ! glyphs_val->get("chars", chars) || chars.size() == 0) {
std::ostringstream msg;
msg << "Font:" << filename << ": missing chars definition";
throw std::runtime_error(msg.str());
- }
+ }
if( local_char_width==0 ) {
std::ostringstream msg;
msg << "Font:" << filename << ": misses glyph-width for some surface";
throw std::runtime_error(msg.str());
- }
+ }
loadFontSurface(glyph_image, shadow_image, chars,
- local_glyph_width, local_char_width);
- }
+ local_glyph_width, local_char_width);
}
+ }
}
void
int char_width
)
{
- Surface glyph_surface = Surface("images/engine/fonts/" + glyphimage);
- Surface shadow_surface = Surface("images/engine/fonts/" + shadowimage);
+ Surface glyph_surface("images/engine/fonts/" + glyphimage);
+ Surface shadow_surface("images/engine/fonts/" + shadowimage);
int surface_idx = glyph_surfaces.size();
glyph_surfaces.push_back(glyph_surface);
std::ostringstream msg;
msg << "Couldn't load image '" << glyphimage << "' :" << SDL_GetError();
throw std::runtime_error(msg.str());
- }
- SDL_LockSurface(surface);
}
+ SDL_LockSurface(surface);
+ }
for( unsigned int i = 0; i < chars.size(); i++) {
for(UTF8Iterator chr(chars[i]); !chr.done(); ++chr) {
glyph.rect = Rect(x, y, x + char_width, y + char_height);
glyph.offset = Vector(0, 0);
glyph.advance = char_width;
- }
+ }
else {
int left = x;
while (left < x + char_width && vline_empty(surface, left, y, y + char_height, 64))
glyph.offset = Vector(0, 0);
glyph.advance = glyph.rect.get_width() + 1; // FIXME: might be useful to make spacing configurable
- }
+ }
glyphs[*chr] = glyph;
- }
+ }
if( col>0 && col <= wrap ) {
col = 0;
row++;
- }
}
+ }
if( surface != NULL ) {
SDL_UnlockSurface(surface);
SDL_FreeSurface(surface);
- }
+ }
}
Font::~Font()
float last_width = 0;
for(UTF8Iterator it(text); !it.done(); ++it)
+ {
+ if (*it == '\n')
+ {
+ last_width = std::max(last_width, curr_width);
+ curr_width = 0;
+ }
+ else
{
- if (*it == '\n')
- {
- last_width = std::max(last_width, curr_width);
- curr_width = 0;
- }
- else
- {
- if( glyphs.at(*it).surface_idx != -1 )
- curr_width += glyphs[*it].advance;
- else
- curr_width += glyphs[0x20].advance;
- }
+ if( glyphs.at(*it).surface_idx != -1 )
+ curr_width += glyphs[*it].advance;
+ else
+ curr_width += glyphs[0x20].advance;
}
+ }
return std::max(curr_width, last_width);
}
std::string::size_type text_height = char_height;
for(std::string::const_iterator it = text.begin(); it != text.end(); ++it)
- { // since UTF8 multibyte characters are decoded with values
- // outside the ASCII range there is no risk of overlapping and
- // thus we don't need to decode the utf-8 string
- if (*it == '\n')
- text_height += char_height + 2;
- }
+ { // since UTF8 multibyte characters are decoded with values
+ // outside the ASCII range there is no risk of overlapping and
+ // thus we don't need to decode the utf-8 string
+ if (*it == '\n')
+ text_height += char_height + 2;
+ }
return text_height;
}
std::string::size_type last = 0;
for(std::string::size_type i = 0;; ++i)
+ {
+ if (text[i] == '\n' || i == text.size())
{
- if (text[i] == '\n' || i == text.size())
- {
- std::string temp = text.substr(last, i - last);
+ std::string temp = text.substr(last, i - last);
- // calculate X positions based on the alignment type
- Vector pos = Vector(x, y);
+ // calculate X positions based on the alignment type
+ Vector pos = Vector(x, y);
- if(alignment == ALIGN_CENTER)
- pos.x -= get_text_width(temp) / 2;
- else if(alignment == ALIGN_RIGHT)
- pos.x -= get_text_width(temp);
+ if(alignment == ALIGN_CENTER)
+ pos.x -= get_text_width(temp) / 2;
+ else if(alignment == ALIGN_RIGHT)
+ pos.x -= get_text_width(temp);
- // Cast font position to integer to get a clean drawing result and
- // no blurring as we would get with subpixel positions
- pos.x = static_cast<int>(pos.x);
+ // Cast font position to integer to get a clean drawing result and
+ // no blurring as we would get with subpixel positions
+ pos.x = static_cast<int>(pos.x);
- draw_text(renderer, temp, pos, drawing_effect, color, alpha);
+ draw_text(renderer, temp, pos, drawing_effect, color, alpha);
- if (i == text.size())
- break;
+ if (i == text.size())
+ break;
- y += char_height + 2;
- last = i + 1;
- }
+ y += char_height + 2;
+ last = i + 1;
}
+ }
}
void
DrawingEffect drawing_effect, Color color, float alpha) const
{
if(shadowsize > 0)
- draw_chars(renderer, false, text,
- pos + Vector(shadowsize, shadowsize), drawing_effect, Color(1,1,1), alpha);
+ draw_chars(renderer, false, text,
+ pos + Vector(shadowsize, shadowsize), drawing_effect, Color(1,1,1), alpha);
draw_chars(renderer, true, text, pos, drawing_effect, color, alpha);
}
Vector p = pos;
for(UTF8Iterator it(text); !it.done(); ++it)
+ {
+ if(*it == '\n')
{
- if(*it == '\n')
- {
- p.x = pos.x;
- p.y += char_height + 2;
- }
- else if(*it == ' ')
- {
- p.x += glyphs[0x20].advance;
- }
- else
- {
- Glyph glyph;
- if( glyphs.at(*it).surface_idx != -1 )
- glyph = glyphs[*it];
- else
- glyph = glyphs[0x20];
-
- DrawingRequest request;
-
- request.pos = p + glyph.offset;
- request.drawing_effect = drawing_effect;
- request.color = color;
- request.alpha = alpha;
-
- SurfacePartRequest surfacepartrequest;
- surfacepartrequest.size = glyph.rect.p2 - glyph.rect.p1;
- surfacepartrequest.source = glyph.rect.p1;
- surfacepartrequest.surface = notshadow ? &(glyph_surfaces[glyph.surface_idx]) : &(shadow_surfaces[glyph.surface_idx]);
-
- request.request_data = &surfacepartrequest;
- renderer->draw_surface_part(request);
-
- p.x += glyph.advance;
- }
+ p.x = pos.x;
+ p.y += char_height + 2;
}
-}
+ else if(*it == ' ')
+ {
+ p.x += glyphs[0x20].advance;
+ }
+ else
+ {
+ Glyph glyph;
+ if( glyphs.at(*it).surface_idx != -1 )
+ glyph = glyphs[*it];
+ else
+ glyph = glyphs[0x20];
+
+ DrawingRequest request;
+ request.pos = p + glyph.offset;
+ request.drawing_effect = drawing_effect;
+ request.color = color;
+ request.alpha = alpha;
+
+ SurfacePartRequest surfacepartrequest;
+ surfacepartrequest.size = glyph.rect.p2 - glyph.rect.p1;
+ surfacepartrequest.source = glyph.rect.p1;
+ surfacepartrequest.surface = notshadow ? &(glyph_surfaces[glyph.surface_idx]) : &(shadow_surfaces[glyph.surface_idx]);
+
+ request.request_data = &surfacepartrequest;
+ renderer->draw_surface_part(request);
+
+ p.x += glyph.advance;
+ }
+ }
+}
namespace {
}
} // namespace
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>,
// Ingo Ruhnke <grumbel@gmx.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef SUPERTUX_FONT_H
-#define SUPERTUX_FONT_H
+#ifndef HEADER_SUPERTUX_VIDEO_FONT_HPP
+#define HEADER_SUPERTUX_VIDEO_FONT_HPP
-#include <string>
#include <stdint.h>
+#include <string>
-#include "video/surface.hpp"
-#include "video/color.hpp"
-#include "math/vector.hpp"
#include "math/rect.hpp"
+#include "math/vector.hpp"
+#include "video/color.hpp"
+#include "video/surface.hpp"
+#include "video/texture.hpp"
class Renderer;
void loadFontFile(const std::string &filename);
void loadFontSurface(const std::string &glyphimage,
- const std::string &shadowimage,
- const std::vector<std::string> &chars,
- GlyphWidth glyph_width,
- int char_width);
+ const std::string &shadowimage,
+ const std::vector<std::string> &chars,
+ GlyphWidth glyph_width,
+ int char_width);
};
#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include "video/gl/gl_lightmap.hpp"
+
+#include <SDL_image.h>
+#include <algorithm>
+#include <cassert>
+#include <functional>
+#include <iomanip>
+#include <iostream>
+#include <math.h>
+#include <physfs.h>
+#include <sstream>
+
+#include "obstack/obstackpp.hpp"
+#include "supertux/gameconfig.hpp"
+#include "supertux/main.hpp"
+#include "video/lightmap.hpp"
+#include "video/drawing_context.hpp"
+#include "video/drawing_request.hpp"
+#include "video/font.hpp"
+#include "video/gl/gl_surface_data.hpp"
+#include "video/gl/gl_texture.hpp"
+#include "video/glutil.hpp"
+#include "video/renderer.hpp"
+#include "video/surface.hpp"
+#include "video/texture_manager.hpp"
+
+namespace {
+
+inline void intern_draw(float left, float top, float right, float bottom,
+ float uv_left, float uv_top,
+ float uv_right, float uv_bottom,
+ float angle, float alpha,
+ const Color& color,
+ const Blend& blend,
+ DrawingEffect effect)
+{
+ if(effect & HORIZONTAL_FLIP)
+ std::swap(uv_left, uv_right);
+
+ if(effect & VERTICAL_FLIP)
+ std::swap(uv_top, uv_bottom);
+
+ // unrotated blit
+ glBlendFunc(blend.sfactor, blend.dfactor);
+ glColor4f(color.red, color.green, color.blue, color.alpha * alpha);
+
+ if (angle == 0.0f) {
+ float vertices[] = {
+ left, top,
+ right, top,
+ right, bottom,
+ left, bottom,
+ };
+ glVertexPointer(2, GL_FLOAT, 0, vertices);
+
+ float uvs[] = {
+ uv_left, uv_top,
+ uv_right, uv_top,
+ uv_right, uv_bottom,
+ uv_left, uv_bottom,
+ };
+ glTexCoordPointer(2, GL_FLOAT, 0, uvs);
+
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+ } else {
+ // rotated blit
+ float center_x = (left + right) / 2;
+ float center_y = (top + bottom) / 2;
+
+ float sa = sinf(angle/180.0f*M_PI);
+ float ca = cosf(angle/180.0f*M_PI);
+
+ left -= center_x;
+ right -= center_x;
+
+ top -= center_y;
+ bottom -= center_y;
+
+ float vertices[] = {
+ left*ca - top*sa + center_x, left*sa + top*ca + center_y,
+ right*ca - top*sa + center_x, right*sa + top*ca + center_y,
+ right*ca - bottom*sa + center_x, right*sa + bottom*ca + center_y,
+ left*ca - bottom*sa + center_x, left*sa + bottom*ca + center_y
+ };
+ glVertexPointer(2, GL_FLOAT, 0, vertices);
+
+ float uvs[] = {
+ uv_left, uv_top,
+ uv_right, uv_top,
+ uv_right, uv_bottom,
+ uv_left, uv_bottom,
+ };
+ glTexCoordPointer(2, GL_FLOAT, 0, uvs);
+
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+ }
+
+ // FIXME: find a better way to restore the blend mode
+ glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+}
+
+static inline int next_po2(int val)
+{
+ int result = 1;
+ while(result < val)
+ result *= 2;
+
+ return result;
+}
+
+} // namespace
+
+GLLightmap::GLLightmap() :
+ screen(),
+ lightmap(),
+ lightmap_width(),
+ lightmap_height(),
+ lightmap_uv_right(),
+ lightmap_uv_bottom()
+{
+ screen = SDL_GetVideoSurface();
+
+ lightmap_width = screen->w / LIGHTMAP_DIV;
+ lightmap_height = screen->h / LIGHTMAP_DIV;
+ unsigned int width = next_po2(lightmap_width);
+ unsigned int height = next_po2(lightmap_height);
+
+ lightmap = new GLTexture(width, height);
+
+ lightmap_uv_right = static_cast<float>(lightmap_width) / static_cast<float>(width);
+ lightmap_uv_bottom = static_cast<float>(lightmap_height) / static_cast<float>(height);
+ texture_manager->register_texture(lightmap);
+}
+
+GLLightmap::~GLLightmap()
+{
+ if(texture_manager){
+ texture_manager->remove_texture(lightmap);
+ }
+ delete lightmap;
+}
+
+void
+GLLightmap::start_draw(const Color &ambient_color)
+{
+ glViewport(0, screen->h - lightmap_height, lightmap_width, lightmap_height);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+#ifdef GL_VERSION_ES_CM_1_0
+ glOrthof(0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, -1.0, 1.0);
+#else
+ glOrtho(0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, -1.0, 1.0);
+#endif
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ glClearColor( ambient_color.red, ambient_color.green, ambient_color.blue, 1 );
+ glClear(GL_COLOR_BUFFER_BIT);
+}
+
+void
+GLLightmap::end_draw()
+{
+ glDisable(GL_BLEND);
+ glBindTexture(GL_TEXTURE_2D, lightmap->get_handle());
+ glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, screen->h - lightmap_height, lightmap_width, lightmap_height);
+
+ glViewport(0, 0, screen->w, screen->h);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+#ifdef GL_VERSION_ES_CM_1_0
+ glOrthof(0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, -1.0, 1.0);
+#else
+ glOrtho(0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, -1.0, 1.0);
+#endif
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glEnable(GL_BLEND);
+ //glClear(GL_COLOR_BUFFER_BIT);
+}
+
+void
+GLLightmap::do_draw()
+{
+ const GLTexture* texture = lightmap;
+
+ // multiple the lightmap with the framebuffer
+ glBlendFunc(GL_DST_COLOR, GL_ZERO);
+
+ glBindTexture(GL_TEXTURE_2D, texture->get_handle());
+
+ float vertices[] = {
+ 0, 0,
+ SCREEN_WIDTH, 0,
+ SCREEN_WIDTH, SCREEN_HEIGHT,
+ 0, SCREEN_HEIGHT
+ };
+ glVertexPointer(2, GL_FLOAT, 0, vertices);
+
+ float uvs[] = {
+ 0, lightmap_uv_bottom,
+ lightmap_uv_right, lightmap_uv_bottom,
+ lightmap_uv_right, 0,
+ 0, 0
+ };
+ glTexCoordPointer(2, GL_FLOAT, 0, uvs);
+
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+}
+
+void
+GLLightmap::draw_surface(const DrawingRequest& request)
+{
+ const Surface* surface = (const Surface*) request.request_data;
+ GLTexture *gltexture = dynamic_cast<GLTexture *>(surface->get_texture());
+ GLSurfaceData *surface_data = reinterpret_cast<GLSurfaceData *>(surface->get_surface_data());
+
+ glBindTexture(GL_TEXTURE_2D, gltexture->get_handle());
+ intern_draw(request.pos.x, request.pos.y,
+ request.pos.x + surface->get_width(),
+ request.pos.y + surface->get_height(),
+ surface_data->get_uv_left(),
+ surface_data->get_uv_top(),
+ surface_data->get_uv_right(),
+ surface_data->get_uv_bottom(),
+ request.angle,
+ request.alpha,
+ request.color,
+ request.blend,
+ request.drawing_effect);
+}
+
+void
+GLLightmap::draw_surface_part(const DrawingRequest& request)
+{
+ const SurfacePartRequest* surfacepartrequest
+ = (SurfacePartRequest*) request.request_data;
+ const Surface *surface = surfacepartrequest->surface;
+ GLTexture *gltexture = dynamic_cast<GLTexture *>(surface->get_texture());
+ GLSurfaceData *surface_data = reinterpret_cast<GLSurfaceData *>(surface->get_surface_data());
+
+ float uv_width = surface_data->get_uv_right() - surface_data->get_uv_left();
+ float uv_height = surface_data->get_uv_bottom() - surface_data->get_uv_top();
+
+ float uv_left = surface_data->get_uv_left() + (uv_width * surfacepartrequest->source.x) / surface->get_width();
+ float uv_top = surface_data->get_uv_top() + (uv_height * surfacepartrequest->source.y) / surface->get_height();
+ float uv_right = surface_data->get_uv_left() + (uv_width * (surfacepartrequest->source.x + surfacepartrequest->size.x)) / surface->get_width();
+ float uv_bottom = surface_data->get_uv_top() + (uv_height * (surfacepartrequest->source.y + surfacepartrequest->size.y)) / surface->get_height();
+
+ glBindTexture(GL_TEXTURE_2D, gltexture->get_handle());
+ intern_draw(request.pos.x, request.pos.y,
+ request.pos.x + surfacepartrequest->size.x,
+ request.pos.y + surfacepartrequest->size.y,
+ uv_left,
+ uv_top,
+ uv_right,
+ uv_bottom,
+ 0.0,
+ request.alpha,
+ Color(1.0, 1.0, 1.0),
+ Blend(),
+ request.drawing_effect);
+}
+
+void
+GLLightmap::draw_gradient(const DrawingRequest& request)
+{
+ const GradientRequest* gradientrequest
+ = (GradientRequest*) request.request_data;
+ const Color& top = gradientrequest->top;
+ const Color& bottom = gradientrequest->bottom;
+
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_TEXTURE_COORD_ARRAY);
+ glEnable(GL_COLOR_ARRAY);
+
+ float vertices[] = {
+ 0, 0,
+ SCREEN_WIDTH, 0,
+ SCREEN_WIDTH, SCREEN_HEIGHT,
+ 0, SCREEN_HEIGHT
+ };
+ glVertexPointer(2, GL_FLOAT, 0, vertices);
+
+ float colors[] = {
+ top.red, top.green, top.blue, top.alpha,
+ top.red, top.green, top.blue, top.alpha,
+ bottom.red, bottom.green, bottom.blue, bottom.alpha,
+ bottom.red, bottom.green, bottom.blue, bottom.alpha,
+ };
+ glColorPointer(4, GL_FLOAT, 0, colors);
+
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ glDisable(GL_COLOR_ARRAY);
+ glEnable(GL_TEXTURE_COORD_ARRAY);
+
+ glEnable(GL_TEXTURE_2D);
+ glColor4f(1, 1, 1, 1);
+}
+
+void
+GLLightmap::draw_filled_rect(const DrawingRequest& request)
+{
+ const FillRectRequest* fillrectrequest
+ = (FillRectRequest*) request.request_data;
+
+ float x = request.pos.x;
+ float y = request.pos.y;
+ float w = fillrectrequest->size.x;
+ float h = fillrectrequest->size.y;
+
+ glDisable(GL_TEXTURE_2D);
+ glColor4f(fillrectrequest->color.red, fillrectrequest->color.green,
+ fillrectrequest->color.blue, fillrectrequest->color.alpha);
+ glDisable(GL_TEXTURE_COORD_ARRAY);
+
+ float vertices[] = {
+ x, y,
+ x+w, y,
+ x+w, y+h,
+ x, y+h
+ };
+ glVertexPointer(2, GL_FLOAT, 0, vertices);
+
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ glEnable(GL_TEXTURE_COORD_ARRAY);
+ glEnable(GL_TEXTURE_2D);
+ glColor4f(1, 1, 1, 1);
+}
+
+void
+GLLightmap::get_light(const DrawingRequest& request) const
+{
+ const GetLightRequest* getlightrequest
+ = (GetLightRequest*) request.request_data;
+
+ float pixels[3];
+ for( int i = 0; i<3; i++)
+ pixels[i] = 0.0f; //set to black
+
+ float posX = request.pos.x * lightmap_width / SCREEN_WIDTH;
+ float posY = screen->h - request.pos.y * lightmap_height / SCREEN_HEIGHT;
+ glReadPixels((GLint) posX, (GLint) posY , 1, 1, GL_RGB, GL_FLOAT, pixels);
+ *(getlightrequest->color_ptr) = Color( pixels[0], pixels[1], pixels[2]);
+}
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_VIDEO_GL_LIGHTMAP_HPP
+#define HEADER_SUPERTUX_VIDEO_GL_LIGHTMAP_HPP
+
+#include "video/lightmap.hpp"
+
+struct DrawingRequest;
+
+class Texture;
+
+class GLLightmap : public Lightmap
+{
+public:
+ GLLightmap();
+ ~GLLightmap();
+
+ void start_draw(const Color &ambient_color);
+ void end_draw();
+ void do_draw();
+ void draw_surface(const DrawingRequest& request);
+ void draw_surface_part(const DrawingRequest& request);
+ void draw_text(const DrawingRequest& request);
+ void draw_gradient(const DrawingRequest& request);
+ void draw_filled_rect(const DrawingRequest& request);
+ void get_light(const DrawingRequest& request) const;
+
+private:
+ static const int LIGHTMAP_DIV = 5;
+
+ SDL_Surface* screen;
+ GLTexture* lightmap;
+ int lightmap_width;
+ int lightmap_height;
+ float lightmap_uv_right;
+ float lightmap_uv_bottom;
+
+private:
+ GLLightmap(const GLLightmap&);
+ GLLightmap& operator=(const GLLightmap&);
+};
+
+#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include "video/gl/gl_renderer.hpp"
+
+#include <iomanip>
+#include <iostream>
+#include <math.h>
+#include <physfs.h>
+
+#include "supertux/gameconfig.hpp"
+#include "supertux/main.hpp"
+#include "video/drawing_request.hpp"
+#include "video/gl/gl_surface_data.hpp"
+#include "video/gl/gl_texture.hpp"
+#define LIGHTMAP_DIV 5
+
+#ifdef GL_VERSION_ES_CM_1_0
+# define glOrtho glOrthof
+#endif
+
+namespace
+{
+
+inline void intern_draw(float left, float top, float right, float bottom,
+ float uv_left, float uv_top,
+ float uv_right, float uv_bottom,
+ float angle, float alpha,
+ const Color& color,
+ const Blend& blend,
+ DrawingEffect effect)
+{
+ if(effect & HORIZONTAL_FLIP)
+ std::swap(uv_left, uv_right);
+
+ if(effect & VERTICAL_FLIP)
+ std::swap(uv_top, uv_bottom);
+
+ // unrotated blit
+ glBlendFunc(blend.sfactor, blend.dfactor);
+ glColor4f(color.red, color.green, color.blue, color.alpha * alpha);
+
+ if (angle == 0.0f) {
+ float vertices[] = {
+ left, top,
+ right, top,
+ right, bottom,
+ left, bottom,
+ };
+ glVertexPointer(2, GL_FLOAT, 0, vertices);
+
+ float uvs[] = {
+ uv_left, uv_top,
+ uv_right, uv_top,
+ uv_right, uv_bottom,
+ uv_left, uv_bottom,
+ };
+ glTexCoordPointer(2, GL_FLOAT, 0, uvs);
+
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+ } else {
+ // rotated blit
+ float center_x = (left + right) / 2;
+ float center_y = (top + bottom) / 2;
+
+ float sa = sinf(angle/180.0f*M_PI);
+ float ca = cosf(angle/180.0f*M_PI);
+
+ left -= center_x;
+ right -= center_x;
+
+ top -= center_y;
+ bottom -= center_y;
+
+ float vertices[] = {
+ left*ca - top*sa + center_x, left*sa + top*ca + center_y,
+ right*ca - top*sa + center_x, right*sa + top*ca + center_y,
+ right*ca - bottom*sa + center_x, right*sa + bottom*ca + center_y,
+ left*ca - bottom*sa + center_x, left*sa + bottom*ca + center_y
+ };
+ glVertexPointer(2, GL_FLOAT, 0, vertices);
+
+ float uvs[] = {
+ uv_left, uv_top,
+ uv_right, uv_top,
+ uv_right, uv_bottom,
+ uv_left, uv_bottom,
+ };
+ glTexCoordPointer(2, GL_FLOAT, 0, uvs);
+
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+ }
+
+ // FIXME: find a better way to restore the blend mode
+ glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+}
+
+} // namespace
+
+GLRenderer::GLRenderer()
+ : desktop_width(-1),
+ desktop_height(-1)
+{
+ Renderer::instance_ = this;
+
+#if SDL_MAJOR_VERSION > 1 || SDL_MINOR_VERSION > 2 || (SDL_MINOR_VERSION == 2 && SDL_PATCHLEVEL >= 10)
+ // unfortunately only newer SDLs have these infos.
+ // This must be called before SDL_SetVideoMode() or it will return
+ // the window size instead of the desktop size.
+ const SDL_VideoInfo *info = SDL_GetVideoInfo();
+ if (info)
+ {
+ desktop_width = info->current_w;
+ desktop_height = info->current_h;
+ }
+#endif
+
+ if(texture_manager != 0)
+ texture_manager->save_textures();
+
+#ifdef SDL_GL_SWAP_CONTROL
+ if(config->try_vsync) {
+ /* we want vsync for smooth scrolling */
+ SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1);
+ }
+#endif
+
+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+
+ // FIXME: Hu? 16bit rendering?
+ SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
+ SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
+ SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
+
+ int flags = SDL_OPENGL;
+ int width;
+ int height;
+
+ if(g_config->use_fullscreen)
+ {
+ flags |= SDL_FULLSCREEN;
+ width = g_config->fullscreen_width;
+ height = g_config->fullscreen_height;
+ }
+ else
+ {
+ // flags |= SDL_RESIZABLE;
+ width = g_config->window_width;
+ height = g_config->window_height;
+ }
+
+ int bpp = 0;
+ SDL_Surface *screen = SDL_SetVideoMode(width, height, bpp, flags);
+
+ if(screen == 0) {
+ std::stringstream msg;
+ msg << "Couldn't set video mode (" << width << "x" << height
+ << "-" << bpp << "bpp): " << SDL_GetError();
+ throw std::runtime_error(msg.str());
+ }
+
+ // setup opengl state and transform
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_CULL_FACE);
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ // Init the projection matrix, viewport and stuff
+ apply_config();
+
+ if(texture_manager == 0)
+ texture_manager = new TextureManager();
+ else
+ texture_manager->reload_textures();
+}
+
+GLRenderer::~GLRenderer()
+{
+}
+
+void
+GLRenderer::draw_surface(const DrawingRequest& request)
+{
+ const Surface* surface = (const Surface*) request.request_data;
+ GLTexture *gltexture = dynamic_cast<GLTexture *>(surface->get_texture());
+ GLSurfaceData *surface_data = reinterpret_cast<GLSurfaceData *>(surface->get_surface_data());
+
+ glBindTexture(GL_TEXTURE_2D, gltexture->get_handle());
+ intern_draw(request.pos.x, request.pos.y,
+ request.pos.x + surface->get_width(),
+ request.pos.y + surface->get_height(),
+ surface_data->get_uv_left(),
+ surface_data->get_uv_top(),
+ surface_data->get_uv_right(),
+ surface_data->get_uv_bottom(),
+ request.angle,
+ request.alpha,
+ request.color,
+ request.blend,
+ request.drawing_effect);
+}
+
+void
+GLRenderer::draw_surface_part(const DrawingRequest& request)
+{
+ const SurfacePartRequest* surfacepartrequest
+ = (SurfacePartRequest*) request.request_data;
+ const Surface *surface = surfacepartrequest->surface;
+ GLTexture *gltexture = dynamic_cast<GLTexture *>(surface->get_texture());
+ GLSurfaceData *surface_data = reinterpret_cast<GLSurfaceData *>(surface->get_surface_data());
+
+ float uv_width = surface_data->get_uv_right() - surface_data->get_uv_left();
+ float uv_height = surface_data->get_uv_bottom() - surface_data->get_uv_top();
+
+ float uv_left = surface_data->get_uv_left() + (uv_width * surfacepartrequest->source.x) / surface->get_width();
+ float uv_top = surface_data->get_uv_top() + (uv_height * surfacepartrequest->source.y) / surface->get_height();
+ float uv_right = surface_data->get_uv_left() + (uv_width * (surfacepartrequest->source.x + surfacepartrequest->size.x)) / surface->get_width();
+ float uv_bottom = surface_data->get_uv_top() + (uv_height * (surfacepartrequest->source.y + surfacepartrequest->size.y)) / surface->get_height();
+
+ glBindTexture(GL_TEXTURE_2D, gltexture->get_handle());
+ intern_draw(request.pos.x, request.pos.y,
+ request.pos.x + surfacepartrequest->size.x,
+ request.pos.y + surfacepartrequest->size.y,
+ uv_left,
+ uv_top,
+ uv_right,
+ uv_bottom,
+ 0.0,
+ request.alpha,
+ request.color,
+ Blend(),
+ request.drawing_effect);
+}
+
+void
+GLRenderer::draw_gradient(const DrawingRequest& request)
+{
+ const GradientRequest* gradientrequest
+ = (GradientRequest*) request.request_data;
+ const Color& top = gradientrequest->top;
+ const Color& bottom = gradientrequest->bottom;
+
+ glDisable(GL_TEXTURE_2D);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glEnableClientState(GL_COLOR_ARRAY);
+
+ float vertices[] = {
+ 0, 0,
+ SCREEN_WIDTH, 0,
+ SCREEN_WIDTH, SCREEN_HEIGHT,
+ 0, SCREEN_HEIGHT
+ };
+ glVertexPointer(2, GL_FLOAT, 0, vertices);
+
+ float colors[] = {
+ top.red, top.green, top.blue, top.alpha,
+ top.red, top.green, top.blue, top.alpha,
+ bottom.red, bottom.green, bottom.blue, bottom.alpha,
+ bottom.red, bottom.green, bottom.blue, bottom.alpha,
+ };
+ glColorPointer(4, GL_FLOAT, 0, colors);
+
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ glDisableClientState(GL_COLOR_ARRAY);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
+ glEnable(GL_TEXTURE_2D);
+ glColor4f(1, 1, 1, 1);
+}
+
+void
+GLRenderer::draw_filled_rect(const DrawingRequest& request)
+{
+ const FillRectRequest* fillrectrequest
+ = (FillRectRequest*) request.request_data;
+
+ glDisable(GL_TEXTURE_2D);
+ glColor4f(fillrectrequest->color.red, fillrectrequest->color.green,
+ fillrectrequest->color.blue, fillrectrequest->color.alpha);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+
+ if (fillrectrequest->radius != 0.0f)
+ {
+ // draw round rect
+ // Keep radius in the limits, so that we get a circle instead of
+ // just graphic junk
+ float radius = std::min(fillrectrequest->radius,
+ std::min(fillrectrequest->size.x/2,
+ fillrectrequest->size.y/2));
+
+ // inner rectangle
+ Rect irect(request.pos.x + radius,
+ request.pos.y + radius,
+ request.pos.x + fillrectrequest->size.x - radius,
+ request.pos.y + fillrectrequest->size.y - radius);
+
+ int n = 8;
+ int p = 0;
+ std::vector<float> vertices((n+1) * 4 * 2);
+
+ for(int i = 0; i <= n; ++i)
+ {
+ float x = sinf(i * (M_PI/2) / n) * radius;
+ float y = cosf(i * (M_PI/2) / n) * radius;
+
+ vertices[p++] = irect.get_left() - x;
+ vertices[p++] = irect.get_top() - y;
+
+ vertices[p++] = irect.get_right() + x;
+ vertices[p++] = irect.get_top() - y;
+ }
+
+ for(int i = 0; i <= n; ++i)
+ {
+ float x = cosf(i * (M_PI/2) / n) * radius;
+ float y = sinf(i * (M_PI/2) / n) * radius;
+
+ vertices[p++] = irect.get_left() - x;
+ vertices[p++] = irect.get_bottom() + y;
+
+ vertices[p++] = irect.get_right() + x;
+ vertices[p++] = irect.get_bottom() + y;
+ }
+
+ glVertexPointer(2, GL_FLOAT, 0, &*vertices.begin());
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, vertices.size()/2);
+ }
+ else
+ {
+ float x = request.pos.x;
+ float y = request.pos.y;
+ float w = fillrectrequest->size.x;
+ float h = fillrectrequest->size.y;
+
+ float vertices[] = {
+ x, y,
+ x+w, y,
+ x+w, y+h,
+ x, y+h
+ };
+ glVertexPointer(2, GL_FLOAT, 0, vertices);
+
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+ }
+
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glEnable(GL_TEXTURE_2D);
+ glColor4f(1, 1, 1, 1);
+}
+
+void
+GLRenderer::draw_inverse_ellipse(const DrawingRequest& request)
+{
+ const InverseEllipseRequest* ellipse = (InverseEllipseRequest*)request.request_data;
+
+ glDisable(GL_TEXTURE_2D);
+ glColor4f(ellipse->color.red, ellipse->color.green,
+ ellipse->color.blue, ellipse->color.alpha);
+
+ float x = request.pos.x;
+ float y = request.pos.y;
+ float w = ellipse->size.x/2.0f;
+ float h = ellipse->size.y/2.0f;
+
+ static const int slices = 16;
+ static const int points = (slices+1) * 12;
+
+ float vertices[points * 2];
+ int p = 0;
+
+ // Bottom
+ vertices[p++] = SCREEN_WIDTH; vertices[p++] = SCREEN_HEIGHT;
+ vertices[p++] = 0; vertices[p++] = SCREEN_HEIGHT;
+ vertices[p++] = x; vertices[p++] = y+h;
+
+ // Top
+ vertices[p++] = SCREEN_WIDTH; vertices[p++] = 0;
+ vertices[p++] = 0; vertices[p++] = 0;
+ vertices[p++] = x; vertices[p++] = y-h;
+
+ // Left
+ vertices[p++] = SCREEN_WIDTH; vertices[p++] = 0;
+ vertices[p++] = SCREEN_WIDTH; vertices[p++] = SCREEN_HEIGHT;
+ vertices[p++] = x+w; vertices[p++] = y;
+
+ // Right
+ vertices[p++] = 0; vertices[p++] = 0;
+ vertices[p++] = 0; vertices[p++] = SCREEN_HEIGHT;
+ vertices[p++] = x-w; vertices[p++] = y;
+
+ for(int i = 0; i < slices; ++i)
+ {
+ float ex1 = sinf(M_PI/2 / slices * i) * w;
+ float ey1 = cosf(M_PI/2 / slices * i) * h;
+
+ float ex2 = sinf(M_PI/2 / slices * (i+1)) * w;
+ float ey2 = cosf(M_PI/2 / slices * (i+1)) * h;
+
+ // Bottom/Right
+ vertices[p++] = SCREEN_WIDTH; vertices[p++] = SCREEN_HEIGHT;
+ vertices[p++] = x + ex1; vertices[p++] = y + ey1;
+ vertices[p++] = x + ex2; vertices[p++] = y + ey2;
+
+ // Top/Left
+ vertices[p++] = 0; vertices[p++] = 0;
+ vertices[p++] = x - ex1; vertices[p++] = y - ey1;
+ vertices[p++] = x - ex2; vertices[p++] = y - ey2;
+
+ // Top/Right
+ vertices[p++] = SCREEN_WIDTH; vertices[p++] = 0;
+ vertices[p++] = x + ex1; vertices[p++] = y - ey1;
+ vertices[p++] = x + ex2; vertices[p++] = y - ey2;
+
+ // Bottom/Left
+ vertices[p++] = 0; vertices[p++] = SCREEN_HEIGHT;
+ vertices[p++] = x - ex1; vertices[p++] = y + ey1;
+ vertices[p++] = x - ex2; vertices[p++] = y + ey2;
+ }
+
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glVertexPointer(2, GL_FLOAT, 0, vertices);
+
+ glDrawArrays(GL_TRIANGLES, 0, points);
+
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
+ glEnable(GL_TEXTURE_2D);
+ glColor4f(1, 1, 1, 1);
+}
+
+void
+GLRenderer::do_take_screenshot()
+{
+ // [Christoph] TODO: Yes, this method also takes care of the actual disk I/O. Split it?
+
+ SDL_Surface *shot_surf;
+ // create surface to hold screenshot
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ shot_surf = SDL_CreateRGBSurface(SDL_SWSURFACE, SCREEN_WIDTH, SCREEN_HEIGHT, 24, 0x00FF0000, 0x0000FF00, 0x000000FF, 0);
+#else
+ shot_surf = SDL_CreateRGBSurface(SDL_SWSURFACE, SCREEN_WIDTH, SCREEN_HEIGHT, 24, 0x000000FF, 0x0000FF00, 0x00FF0000, 0);
+#endif
+ if (!shot_surf) {
+ log_warning << "Could not create RGB Surface to contain screenshot" << std::endl;
+ return;
+ }
+
+ // read pixels into array
+ char* pixels = new char[3 * SCREEN_WIDTH * SCREEN_HEIGHT];
+ if (!pixels) {
+ log_warning << "Could not allocate memory to store screenshot" << std::endl;
+ SDL_FreeSurface(shot_surf);
+ return;
+ }
+ glReadPixels(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, GL_RGB, GL_UNSIGNED_BYTE, pixels);
+
+ // copy array line-by-line
+ for (int i = 0; i < SCREEN_HEIGHT; i++) {
+ char* src = pixels + (3 * SCREEN_WIDTH * (SCREEN_HEIGHT - i - 1));
+ if(SDL_MUSTLOCK(shot_surf))
+ {
+ SDL_LockSurface(shot_surf);
+ }
+ char* dst = ((char*)shot_surf->pixels) + i * shot_surf->pitch;
+ memcpy(dst, src, 3 * SCREEN_WIDTH);
+ if(SDL_MUSTLOCK(shot_surf))
+ {
+ SDL_UnlockSurface(shot_surf);
+ }
+ }
+
+ // free array
+ delete[](pixels);
+
+ // save screenshot
+ static const std::string writeDir = PHYSFS_getWriteDir();
+ static const std::string dirSep = PHYSFS_getDirSeparator();
+ static const std::string baseName = "screenshot";
+ static const std::string fileExt = ".bmp";
+ std::string fullFilename;
+ for (int num = 0; num < 1000; num++) {
+ std::ostringstream oss;
+ oss << baseName;
+ oss << std::setw(3) << std::setfill('0') << num;
+ oss << fileExt;
+ std::string fileName = oss.str();
+ fullFilename = writeDir + dirSep + fileName;
+ if (!PHYSFS_exists(fileName.c_str())) {
+ SDL_SaveBMP(shot_surf, fullFilename.c_str());
+ log_debug << "Wrote screenshot to \"" << fullFilename << "\"" << std::endl;
+ SDL_FreeSurface(shot_surf);
+ return;
+ }
+ }
+ log_warning << "Did not save screenshot, because all files up to \"" << fullFilename << "\" already existed" << std::endl;
+ SDL_FreeSurface(shot_surf);
+}
+
+void
+GLRenderer::flip()
+{
+ assert_gl("drawing");
+ SDL_GL_SwapBuffers();
+}
+
+void
+GLRenderer::resize(int w, int h)
+{
+ // This causes the screen to go black, which is annoying, but seems
+ // unavoidable with SDL at the moment
+ SDL_SetVideoMode(w, h, 0, SDL_OPENGL /*| SDL_RESIZABLE*/);
+
+ g_config->window_width = w;
+ g_config->window_height = h;
+
+ apply_config();
+}
+
+void
+GLRenderer::apply_config()
+{
+ if (1)
+ {
+ std::cout << "Applying Config:"
+ << "\n Desktop: " << desktop_width << "x" << desktop_height
+ << "\n Window: " << g_config->window_width << "x" << g_config->window_height
+ << "\n FullRes: " << g_config->fullscreen_width << "x" << g_config->fullscreen_height
+ << "\n Aspect: " << g_config->aspect_width << ":" << g_config->aspect_height
+ << "\n Magnif: " << g_config->magnification
+ << std::endl;
+ }
+
+ float target_aspect = static_cast<float>(desktop_width) / static_cast<float>(desktop_height);
+
+ if (g_config->aspect_width != 0 && g_config->aspect_height != 0)
+ target_aspect = float(g_config->aspect_width) / float(g_config->aspect_height);
+
+ float desktop_aspect = 4.0f / 3.0f; // random default fallback guess
+
+ if (desktop_width != -1 && desktop_height != -1)
+ {
+ desktop_aspect = float(desktop_width) / float(desktop_height);
+ }
+
+ int w,h;
+
+ // Get the screen width
+ if (g_config->use_fullscreen)
+ {
+ w = g_config->fullscreen_width;
+ h = g_config->fullscreen_height;
+ desktop_aspect = float(w) / float(h);
+ }
+ else
+ {
+ w = g_config->window_width;
+ h = g_config->window_height;
+ }
+
+ if (target_aspect > 1.0f)
+ {
+ SCREEN_WIDTH = static_cast<int>(w * (target_aspect / desktop_aspect));
+ SCREEN_HEIGHT = static_cast<int>(h);
+ }
+ else
+ {
+ SCREEN_WIDTH = static_cast<int>(w);
+ SCREEN_HEIGHT = static_cast<int>(h * (target_aspect / desktop_aspect));
+ }
+
+ int max_width = 1600; // FIXME: Maybe 1920 is ok too
+ int max_height = 1200;
+
+ if (g_config->magnification == 0.0f) // Magic value that means 'minfill'
+ {
+ // This scales SCREEN_WIDTH/SCREEN_HEIGHT so that they never excede
+ // max_width/max_height
+ if (SCREEN_WIDTH > max_width || SCREEN_HEIGHT > max_height)
+ {
+ float scale1 = float(max_width)/SCREEN_WIDTH;
+ float scale2 = float(max_height)/SCREEN_HEIGHT;
+ float scale = (scale1 < scale2) ? scale1 : scale2;
+ SCREEN_WIDTH = static_cast<int>(SCREEN_WIDTH * scale);
+ SCREEN_HEIGHT = static_cast<int>(SCREEN_HEIGHT * scale);
+ }
+
+ glViewport(0, 0, w, h);
+ }
+ else
+ {
+ SCREEN_WIDTH = static_cast<int>(SCREEN_WIDTH / g_config->magnification);
+ SCREEN_HEIGHT = static_cast<int>(SCREEN_HEIGHT / g_config->magnification);
+
+ // This works by adding black borders around the screen to limit
+ // SCREEN_WIDTH/SCREEN_HEIGHT to max_width/max_height
+ int nw = w;
+ int nh = h;
+
+ if (SCREEN_WIDTH > max_width)
+ {
+ nw = static_cast<int>((float) nw * float(max_width)/SCREEN_WIDTH);
+ SCREEN_WIDTH = static_cast<int>(max_width);
+ }
+
+ if (SCREEN_HEIGHT > max_height)
+ {
+ nh = static_cast<int>((float) nh * float(max_height)/SCREEN_HEIGHT);
+ SCREEN_HEIGHT = static_cast<int>(max_height);
+ }
+
+ // Clear both buffers so that we get a clean black border without junk
+ glClear(GL_COLOR_BUFFER_BIT);
+ SDL_GL_SwapBuffers();
+ glClear(GL_COLOR_BUFFER_BIT);
+ SDL_GL_SwapBuffers();
+
+ if (0)
+ std::cout << (w-nw)/2 << " "
+ << (h-nh)/2 << " "
+ << nw << "x" << nh << std::endl;
+
+ glViewport(std::max(0, (w-nw)/2),
+ std::max(0, (h-nh)/2),
+ std::min(nw, w),
+ std::min(nh, h));
+ }
+
+ if (0)
+ std::cout << " -> " << SCREEN_WIDTH << "x" << SCREEN_HEIGHT << std::endl;
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+
+ glOrtho(0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, -1, 1);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef(0, 0, 0);
+ check_gl_error("Setting up view matrices");
+}
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_VIDEO_GL_RENDERER_HPP
+#define HEADER_SUPERTUX_VIDEO_GL_RENDERER_HPP
+
+#include "video/renderer.hpp"
+
+class GLRenderer : public Renderer
+{
+private:
+ int desktop_width;
+ int desktop_height;
+
+public:
+ GLRenderer();
+ ~GLRenderer();
+
+ void draw_surface(const DrawingRequest& request);
+ void draw_surface_part(const DrawingRequest& request);
+ void draw_text(const DrawingRequest& request);
+ void draw_gradient(const DrawingRequest& request);
+ void draw_filled_rect(const DrawingRequest& request);
+ void draw_inverse_ellipse(const DrawingRequest& request);
+ void do_take_screenshot();
+ void flip();
+ void resize(int w, int h);
+ void apply_config();
+};
+
+#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_VIDEO_GL_SURFACE_DATA_HPP
+#define HEADER_SUPERTUX_VIDEO_GL_SURFACE_DATA_HPP
+
+#include "video/surface.hpp"
+
+class GLSurfaceData
+{
+private:
+ const Surface &surface;
+ float uv_left;
+ float uv_top;
+ float uv_right;
+ float uv_bottom;
+
+public:
+ GLSurfaceData(const Surface &surface) :
+ surface(surface),
+ uv_left((float) surface.get_x() / surface.get_texture()->get_texture_width()),
+ uv_top((float) surface.get_y() / surface.get_texture()->get_texture_height()),
+ uv_right((float) (surface.get_x() + surface.get_width()) / surface.get_texture()->get_texture_width()),
+ uv_bottom((float) (surface.get_y() + surface.get_height()) / surface.get_texture()->get_texture_height())
+ {
+ }
+
+ float get_uv_left() const
+ {
+ return surface.get_flipx() ? uv_right : uv_left;
+ }
+
+ float get_uv_top() const
+ {
+ return uv_top;
+ }
+
+ float get_uv_right() const
+ {
+ return surface.get_flipx() ? uv_left : uv_right;
+ }
+
+ float get_uv_bottom() const
+ {
+ return uv_bottom;
+ }
+};
+
+#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include "supertux/gameconfig.hpp"
+#include "video/gl/gl_texture.hpp"
+
+namespace {
+
+inline bool is_power_of_2(int v)
+{
+ return (v & (v-1)) == 0;
+}
+
+inline int next_power_of_two(int val)
+{
+ int result = 1;
+ while(result < val)
+ result *= 2;
+ return result;
+}
+
+} // namespace
+
+GLTexture::GLTexture(unsigned int width, unsigned int height)
+{
+ assert(is_power_of_2(width));
+ assert(is_power_of_2(height));
+ texture_width = width;
+ texture_height = height;
+ image_width = width;
+ image_height = height;
+
+ assert_gl("before creating texture");
+ glGenTextures(1, &handle);
+
+ try {
+ glBindTexture(GL_TEXTURE_2D, handle);
+
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture_width,
+ texture_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
+
+ set_texture_params();
+ } catch(...) {
+ glDeleteTextures(1, &handle);
+ throw;
+ }
+}
+
+GLTexture::GLTexture(SDL_Surface* image)
+{
+ texture_width = next_power_of_two(image->w);
+ texture_height = next_power_of_two(image->h);
+ image_width = image->w;
+ image_height = image->h;
+
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ SDL_Surface* convert = SDL_CreateRGBSurface(SDL_SWSURFACE,
+ texture_width, texture_height, 32,
+ 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff);
+#else
+ SDL_Surface* convert = SDL_CreateRGBSurface(SDL_SWSURFACE,
+ texture_width, texture_height, 32,
+ 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
+#endif
+
+ if(convert == 0) {
+ throw std::runtime_error("Couldn't create texture: out of memory");
+ }
+
+ SDL_SetAlpha(image, 0, 0);
+ SDL_BlitSurface(image, 0, convert, 0);
+
+ assert_gl("before creating texture");
+ glGenTextures(1, &handle);
+
+ try {
+ GLenum sdl_format;
+ if(convert->format->BytesPerPixel == 3)
+ sdl_format = GL_RGB;
+ else if(convert->format->BytesPerPixel == 4)
+ sdl_format = GL_RGBA;
+ else
+ assert(false);
+
+ glBindTexture(GL_TEXTURE_2D, handle);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+#ifdef GL_UNPACK_ROW_LENGTH
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, convert->pitch/convert->format->BytesPerPixel);
+#else
+ /* OpenGL ES doesn't support UNPACK_ROW_LENGTH, let's hope SDL didn't add
+ * padding bytes, otherwise we need some extra code here... */
+ assert(convert->pitch == texture_width * convert->format->BytesPerPixel);
+#endif
+
+ if(SDL_MUSTLOCK(convert))
+ {
+ SDL_LockSurface(convert);
+ }
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture_width,
+ texture_height, 0, sdl_format,
+ GL_UNSIGNED_BYTE, convert->pixels);
+ if(SDL_MUSTLOCK(convert))
+ {
+ SDL_UnlockSurface(convert);
+ }
+
+ assert_gl("creating texture");
+
+ set_texture_params();
+ } catch(...) {
+ glDeleteTextures(1, &handle);
+ SDL_FreeSurface(convert);
+ throw;
+ }
+ SDL_FreeSurface(convert);
+}
+
+GLTexture::~GLTexture()
+{
+ glDeleteTextures(1, &handle);
+}
+
+void
+GLTexture::set_texture_params()
+{
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+#ifdef GL_CLAMP
+ /* OpenGL ES doesn't support it */
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+#endif
+
+ assert_gl("set texture params");
+}
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_VIDEO_GL_TEXTURE_HPP
+#define HEADER_SUPERTUX_VIDEO_GL_TEXTURE_HPP
+
+#include "video/texture.hpp"
+
+/**
+ * This class is a wrapper around a texture handle. It stores the texture width
+ * and height and provides convenience functions for uploading SDL_Surfaces
+ * into the texture
+ */
+class GLTexture : public Texture
+{
+protected:
+ GLuint handle;
+ unsigned int texture_width;
+ unsigned int texture_height;
+ unsigned int image_width;
+ unsigned int image_height;
+
+public:
+ GLTexture(unsigned int width, unsigned int height);
+ GLTexture(SDL_Surface* image);
+ ~GLTexture();
+
+ const GLuint &get_handle() const {
+ return handle;
+ }
+
+ void set_handle(GLuint handle) {
+ this->handle = handle;
+ }
+
+ unsigned int get_texture_width() const
+ {
+ return texture_width;
+ }
+
+ unsigned int get_texture_height() const
+ {
+ return texture_height;
+ }
+
+ unsigned int get_image_width() const
+ {
+ return image_width;
+ }
+
+ unsigned int get_image_height() const
+ {
+ return image_height;
+ }
+
+ void set_image_width(unsigned int width)
+ {
+ image_width = width;
+ }
+
+ void set_image_height(unsigned int height)
+ {
+ image_height = height;
+ }
+
+private:
+ void set_texture_params();
+};
+
+#endif
+
+/* EOF */
+++ /dev/null
-// $Id: gl_lightmap.cpp 5063 2007-05-27 11:32:00Z matzeb $
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include <config.h>
-
-#ifdef HAVE_OPENGL
-
-#include <functional>
-#include <algorithm>
-#include <cassert>
-#include <math.h>
-#include <iostream>
-#include <SDL_image.h>
-#include <sstream>
-#include <iomanip>
-#include <physfs.h>
-
-#include "glutil.hpp"
-#include "gl_lightmap.hpp"
-#include "gl_surface_data.hpp"
-#include "drawing_context.hpp"
-#include "drawing_request.hpp"
-#include "renderer.hpp"
-#include "surface.hpp"
-#include "font.hpp"
-#include "main.hpp"
-#include "gameconfig.hpp"
-#include "gl_texture.hpp"
-#include "texture_manager.hpp"
-#include "obstack/obstackpp.hpp"
-
-namespace
-{
-
-inline void intern_draw(float left, float top, float right, float bottom,
- float uv_left, float uv_top,
- float uv_right, float uv_bottom,
- float angle, float alpha,
- const Color& color,
- const Blend& blend,
- DrawingEffect effect)
-{
- if(effect & HORIZONTAL_FLIP)
- std::swap(uv_left, uv_right);
-
- if(effect & VERTICAL_FLIP)
- std::swap(uv_top, uv_bottom);
-
- // unrotated blit
- glBlendFunc(blend.sfactor, blend.dfactor);
- glColor4f(color.red, color.green, color.blue, color.alpha * alpha);
-
- if (angle == 0.0f) {
- float vertices[] = {
- left, top,
- right, top,
- right, bottom,
- left, bottom,
- };
- glVertexPointer(2, GL_FLOAT, 0, vertices);
-
- float uvs[] = {
- uv_left, uv_top,
- uv_right, uv_top,
- uv_right, uv_bottom,
- uv_left, uv_bottom,
- };
- glTexCoordPointer(2, GL_FLOAT, 0, uvs);
-
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- } else {
- // rotated blit
- float center_x = (left + right) / 2;
- float center_y = (top + bottom) / 2;
-
- float sa = sinf(angle/180.0f*M_PI);
- float ca = cosf(angle/180.0f*M_PI);
-
- left -= center_x;
- right -= center_x;
-
- top -= center_y;
- bottom -= center_y;
-
- float vertices[] = {
- left*ca - top*sa + center_x, left*sa + top*ca + center_y,
- right*ca - top*sa + center_x, right*sa + top*ca + center_y,
- right*ca - bottom*sa + center_x, right*sa + bottom*ca + center_y,
- left*ca - bottom*sa + center_x, left*sa + bottom*ca + center_y
- };
- glVertexPointer(2, GL_FLOAT, 0, vertices);
-
- float uvs[] = {
- uv_left, uv_top,
- uv_right, uv_top,
- uv_right, uv_bottom,
- uv_left, uv_bottom,
- };
- glTexCoordPointer(2, GL_FLOAT, 0, uvs);
-
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- }
-
- // FIXME: find a better way to restore the blend mode
- glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-}
-
-}
-
-namespace GL
-{
- static inline int next_po2(int val)
- {
- int result = 1;
- while(result < val)
- result *= 2;
-
- return result;
- }
-
- Lightmap::Lightmap()
- {
- screen = SDL_GetVideoSurface();
-
- lightmap_width = screen->w / LIGHTMAP_DIV;
- lightmap_height = screen->h / LIGHTMAP_DIV;
- unsigned int width = next_po2(lightmap_width);
- unsigned int height = next_po2(lightmap_height);
-
- lightmap = new Texture(width, height);
-
- lightmap_uv_right = static_cast<float>(lightmap_width) / static_cast<float>(width);
- lightmap_uv_bottom = static_cast<float>(lightmap_height) / static_cast<float>(height);
- texture_manager->register_texture(lightmap);
- }
-
- Lightmap::~Lightmap()
- {
- if(texture_manager){
- texture_manager->remove_texture(lightmap);
- }
- delete lightmap;
- }
-
- void
- Lightmap::start_draw(const Color &ambient_color)
- {
- glViewport(0, screen->h - lightmap_height, lightmap_width, lightmap_height);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
-#ifdef GL_VERSION_ES_CM_1_0
- glOrthof(0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, -1.0, 1.0);
-#else
- glOrtho(0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, -1.0, 1.0);
-#endif
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
-
- glClearColor( ambient_color.red, ambient_color.green, ambient_color.blue, 1 );
- glClear(GL_COLOR_BUFFER_BIT);
- }
-
- void
- Lightmap::end_draw()
- {
- glDisable(GL_BLEND);
- glBindTexture(GL_TEXTURE_2D, lightmap->get_handle());
- glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, screen->h - lightmap_height, lightmap_width, lightmap_height);
-
- glViewport(0, 0, screen->w, screen->h);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
-#ifdef GL_VERSION_ES_CM_1_0
- glOrthof(0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, -1.0, 1.0);
-#else
- glOrtho(0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, -1.0, 1.0);
-#endif
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glEnable(GL_BLEND);
- //glClear(GL_COLOR_BUFFER_BIT);
- }
-
- void
- Lightmap::do_draw()
- {
- const Texture* texture = lightmap;
-
- // multiple the lightmap with the framebuffer
- glBlendFunc(GL_DST_COLOR, GL_ZERO);
-
- glBindTexture(GL_TEXTURE_2D, texture->get_handle());
-
- float vertices[] = {
- 0, 0,
- SCREEN_WIDTH, 0,
- SCREEN_WIDTH, SCREEN_HEIGHT,
- 0, SCREEN_HEIGHT
- };
- glVertexPointer(2, GL_FLOAT, 0, vertices);
-
- float uvs[] = {
- 0, lightmap_uv_bottom,
- lightmap_uv_right, lightmap_uv_bottom,
- lightmap_uv_right, 0,
- 0, 0
- };
- glTexCoordPointer(2, GL_FLOAT, 0, uvs);
-
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- }
-
- void
- Lightmap::draw_surface(const DrawingRequest& request)
- {
- const Surface* surface = (const Surface*) request.request_data;
- GL::Texture *gltexture = dynamic_cast<GL::Texture *>(surface->get_texture());
- GL::SurfaceData *surface_data = reinterpret_cast<GL::SurfaceData *>(surface->get_surface_data());
-
- glBindTexture(GL_TEXTURE_2D, gltexture->get_handle());
- intern_draw(request.pos.x, request.pos.y,
- request.pos.x + surface->get_width(),
- request.pos.y + surface->get_height(),
- surface_data->get_uv_left(),
- surface_data->get_uv_top(),
- surface_data->get_uv_right(),
- surface_data->get_uv_bottom(),
- request.angle,
- request.alpha,
- request.color,
- request.blend,
- request.drawing_effect);
- }
-
- void
- Lightmap::draw_surface_part(const DrawingRequest& request)
- {
- const SurfacePartRequest* surfacepartrequest
- = (SurfacePartRequest*) request.request_data;
- const Surface *surface = surfacepartrequest->surface;
- GL::Texture *gltexture = dynamic_cast<GL::Texture *>(surface->get_texture());
- GL::SurfaceData *surface_data = reinterpret_cast<GL::SurfaceData *>(surface->get_surface_data());
-
- float uv_width = surface_data->get_uv_right() - surface_data->get_uv_left();
- float uv_height = surface_data->get_uv_bottom() - surface_data->get_uv_top();
-
- float uv_left = surface_data->get_uv_left() + (uv_width * surfacepartrequest->source.x) / surface->get_width();
- float uv_top = surface_data->get_uv_top() + (uv_height * surfacepartrequest->source.y) / surface->get_height();
- float uv_right = surface_data->get_uv_left() + (uv_width * (surfacepartrequest->source.x + surfacepartrequest->size.x)) / surface->get_width();
- float uv_bottom = surface_data->get_uv_top() + (uv_height * (surfacepartrequest->source.y + surfacepartrequest->size.y)) / surface->get_height();
-
- glBindTexture(GL_TEXTURE_2D, gltexture->get_handle());
- intern_draw(request.pos.x, request.pos.y,
- request.pos.x + surfacepartrequest->size.x,
- request.pos.y + surfacepartrequest->size.y,
- uv_left,
- uv_top,
- uv_right,
- uv_bottom,
- 0.0,
- request.alpha,
- Color(1.0, 1.0, 1.0),
- Blend(),
- request.drawing_effect);
- }
-
- void
- Lightmap::draw_gradient(const DrawingRequest& request)
- {
- const GradientRequest* gradientrequest
- = (GradientRequest*) request.request_data;
- const Color& top = gradientrequest->top;
- const Color& bottom = gradientrequest->bottom;
-
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_TEXTURE_COORD_ARRAY);
- glEnable(GL_COLOR_ARRAY);
-
- float vertices[] = {
- 0, 0,
- SCREEN_WIDTH, 0,
- SCREEN_WIDTH, SCREEN_HEIGHT,
- 0, SCREEN_HEIGHT
- };
- glVertexPointer(2, GL_FLOAT, 0, vertices);
-
- float colors[] = {
- top.red, top.green, top.blue, top.alpha,
- top.red, top.green, top.blue, top.alpha,
- bottom.red, bottom.green, bottom.blue, bottom.alpha,
- bottom.red, bottom.green, bottom.blue, bottom.alpha,
- };
- glColorPointer(4, GL_FLOAT, 0, colors);
-
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
- glDisable(GL_COLOR_ARRAY);
- glEnable(GL_TEXTURE_COORD_ARRAY);
-
- glEnable(GL_TEXTURE_2D);
- glColor4f(1, 1, 1, 1);
- }
-
- void
- Lightmap::draw_filled_rect(const DrawingRequest& request)
- {
- const FillRectRequest* fillrectrequest
- = (FillRectRequest*) request.request_data;
-
- float x = request.pos.x;
- float y = request.pos.y;
- float w = fillrectrequest->size.x;
- float h = fillrectrequest->size.y;
-
- glDisable(GL_TEXTURE_2D);
- glColor4f(fillrectrequest->color.red, fillrectrequest->color.green,
- fillrectrequest->color.blue, fillrectrequest->color.alpha);
- glDisable(GL_TEXTURE_COORD_ARRAY);
-
- float vertices[] = {
- x, y,
- x+w, y,
- x+w, y+h,
- x, y+h
- };
- glVertexPointer(2, GL_FLOAT, 0, vertices);
-
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
- glEnable(GL_TEXTURE_COORD_ARRAY);
- glEnable(GL_TEXTURE_2D);
- glColor4f(1, 1, 1, 1);
- }
-
- void
- Lightmap::get_light(const DrawingRequest& request) const
- {
- const GetLightRequest* getlightrequest
- = (GetLightRequest*) request.request_data;
-
- float pixels[3];
- for( int i = 0; i<3; i++)
- pixels[i] = 0.0f; //set to black
-
- float posX = request.pos.x * lightmap_width / SCREEN_WIDTH;
- float posY = screen->h - request.pos.y * lightmap_height / SCREEN_HEIGHT;
- glReadPixels((GLint) posX, (GLint) posY , 1, 1, GL_RGB, GL_FLOAT, pixels);
- *(getlightrequest->color_ptr) = Color( pixels[0], pixels[1], pixels[2]);
- }
-}
-
-#endif
+++ /dev/null
-// $Id: gl_lightmap.hpp 4986 2007-04-16 17:48:28Z matzeb $
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include <config.h>
-
-#ifdef HAVE_OPENGL
-
-#ifndef SUPERTUX_GL_LIGHTMAP_H
-#define SUPERTUX_GL_LIGHTMAP_H
-
-#include <SDL_video.h>
-
-#include "lightmap.hpp"
-
-struct DrawingRequest;
-
-namespace GL
-{
- class Texture;
- class Lightmap : public ::Lightmap
- {
- public:
- Lightmap();
- ~Lightmap();
-
- void start_draw(const Color &ambient_color);
- void end_draw();
- void do_draw();
- void draw_surface(const DrawingRequest& request);
- void draw_surface_part(const DrawingRequest& request);
- void draw_text(const DrawingRequest& request);
- void draw_gradient(const DrawingRequest& request);
- void draw_filled_rect(const DrawingRequest& request);
- void get_light(const DrawingRequest& request) const;
-
- private:
- static const int LIGHTMAP_DIV = 5;
-
- SDL_Surface* screen;
- Texture* lightmap;
- int lightmap_width, lightmap_height;
- float lightmap_uv_right, lightmap_uv_bottom;
- };
-}
-
-#endif
-
-#endif
+++ /dev/null
-// $Id: gl_renderer.cpp 5063 2007-05-27 11:32:00Z matzeb $
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include <config.h>
-
-#ifdef HAVE_OPENGL
-
-#include <functional>
-#include <algorithm>
-#include <cassert>
-#include <math.h>
-#include <iostream>
-#include <SDL_image.h>
-#include <sstream>
-#include <iomanip>
-#include <physfs.h>
-
-#include "glutil.hpp"
-#include "gl_renderer.hpp"
-#include "gl_texture.hpp"
-#include "gl_surface_data.hpp"
-#include "drawing_context.hpp"
-#include "drawing_request.hpp"
-#include "surface.hpp"
-#include "font.hpp"
-#include "main.hpp"
-#include "gameconfig.hpp"
-#include "texture.hpp"
-#include "texture_manager.hpp"
-#include "obstack/obstackpp.hpp"
-#define LIGHTMAP_DIV 5
-
-#ifdef GL_VERSION_ES_CM_1_0
-# define glOrtho glOrthof
-#endif
-
-namespace
-{
-
-inline void intern_draw(float left, float top, float right, float bottom,
- float uv_left, float uv_top,
- float uv_right, float uv_bottom,
- float angle, float alpha,
- const Color& color,
- const Blend& blend,
- DrawingEffect effect)
-{
- if(effect & HORIZONTAL_FLIP)
- std::swap(uv_left, uv_right);
-
- if(effect & VERTICAL_FLIP)
- std::swap(uv_top, uv_bottom);
-
- // unrotated blit
- glBlendFunc(blend.sfactor, blend.dfactor);
- glColor4f(color.red, color.green, color.blue, color.alpha * alpha);
-
- if (angle == 0.0f) {
- float vertices[] = {
- left, top,
- right, top,
- right, bottom,
- left, bottom,
- };
- glVertexPointer(2, GL_FLOAT, 0, vertices);
-
- float uvs[] = {
- uv_left, uv_top,
- uv_right, uv_top,
- uv_right, uv_bottom,
- uv_left, uv_bottom,
- };
- glTexCoordPointer(2, GL_FLOAT, 0, uvs);
-
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- } else {
- // rotated blit
- float center_x = (left + right) / 2;
- float center_y = (top + bottom) / 2;
-
- float sa = sinf(angle/180.0f*M_PI);
- float ca = cosf(angle/180.0f*M_PI);
-
- left -= center_x;
- right -= center_x;
-
- top -= center_y;
- bottom -= center_y;
-
- float vertices[] = {
- left*ca - top*sa + center_x, left*sa + top*ca + center_y,
- right*ca - top*sa + center_x, right*sa + top*ca + center_y,
- right*ca - bottom*sa + center_x, right*sa + bottom*ca + center_y,
- left*ca - bottom*sa + center_x, left*sa + bottom*ca + center_y
- };
- glVertexPointer(2, GL_FLOAT, 0, vertices);
-
- float uvs[] = {
- uv_left, uv_top,
- uv_right, uv_top,
- uv_right, uv_bottom,
- uv_left, uv_bottom,
- };
- glTexCoordPointer(2, GL_FLOAT, 0, uvs);
-
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- }
-
- // FIXME: find a better way to restore the blend mode
- glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-}
-
-}
-
-namespace GL {
-
-Renderer::Renderer()
- : desktop_width(-1),
- desktop_height(-1)
-{
- ::Renderer::instance_ = this;
-
-#if SDL_MAJOR_VERSION > 1 || SDL_MINOR_VERSION > 2 || (SDL_MINOR_VERSION == 2 && SDL_PATCHLEVEL >= 10)
- // unfortunately only newer SDLs have these infos.
- // This must be called before SDL_SetVideoMode() or it will return
- // the window size instead of the desktop size.
- const SDL_VideoInfo *info = SDL_GetVideoInfo();
- if (info)
- {
- desktop_width = info->current_w;
- desktop_height = info->current_h;
- }
-#endif
-
- if(texture_manager != 0)
- texture_manager->save_textures();
-
-#ifdef SDL_GL_SWAP_CONTROL
- if(config->try_vsync) {
- /* we want vsync for smooth scrolling */
- SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1);
- }
-#endif
-
- SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
-
- // FIXME: Hu? 16bit rendering?
- SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
- SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
- SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
-
- int flags = SDL_OPENGL;
- int width;
- int height;
-
- if(config->use_fullscreen)
- {
- flags |= SDL_FULLSCREEN;
- width = config->fullscreen_width;
- height = config->fullscreen_height;
- }
- else
- {
-// flags |= SDL_RESIZABLE;
- width = config->window_width;
- height = config->window_height;
- }
-
- int bpp = 0;
- SDL_Surface *screen = SDL_SetVideoMode(width, height, bpp, flags);
-
- if(screen == 0) {
- std::stringstream msg;
- msg << "Couldn't set video mode (" << width << "x" << height
- << "-" << bpp << "bpp): " << SDL_GetError();
- throw std::runtime_error(msg.str());
- }
-
- // setup opengl state and transform
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_CULL_FACE);
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- // Init the projection matrix, viewport and stuff
- apply_config();
-
- if(texture_manager == 0)
- texture_manager = new TextureManager();
- else
- texture_manager->reload_textures();
-}
-
-Renderer::~Renderer()
-{
-}
-
-void
-Renderer::draw_surface(const DrawingRequest& request)
-{
- const Surface* surface = (const Surface*) request.request_data;
- GL::Texture *gltexture = dynamic_cast<GL::Texture *>(surface->get_texture());
- GL::SurfaceData *surface_data = reinterpret_cast<GL::SurfaceData *>(surface->get_surface_data());
-
- glBindTexture(GL_TEXTURE_2D, gltexture->get_handle());
- intern_draw(request.pos.x, request.pos.y,
- request.pos.x + surface->get_width(),
- request.pos.y + surface->get_height(),
- surface_data->get_uv_left(),
- surface_data->get_uv_top(),
- surface_data->get_uv_right(),
- surface_data->get_uv_bottom(),
- request.angle,
- request.alpha,
- request.color,
- request.blend,
- request.drawing_effect);
-}
-
-void
-Renderer::draw_surface_part(const DrawingRequest& request)
-{
- const SurfacePartRequest* surfacepartrequest
- = (SurfacePartRequest*) request.request_data;
- const Surface *surface = surfacepartrequest->surface;
- GL::Texture *gltexture = dynamic_cast<GL::Texture *>(surface->get_texture());
- GL::SurfaceData *surface_data = reinterpret_cast<GL::SurfaceData *>(surface->get_surface_data());
-
- float uv_width = surface_data->get_uv_right() - surface_data->get_uv_left();
- float uv_height = surface_data->get_uv_bottom() - surface_data->get_uv_top();
-
- float uv_left = surface_data->get_uv_left() + (uv_width * surfacepartrequest->source.x) / surface->get_width();
- float uv_top = surface_data->get_uv_top() + (uv_height * surfacepartrequest->source.y) / surface->get_height();
- float uv_right = surface_data->get_uv_left() + (uv_width * (surfacepartrequest->source.x + surfacepartrequest->size.x)) / surface->get_width();
- float uv_bottom = surface_data->get_uv_top() + (uv_height * (surfacepartrequest->source.y + surfacepartrequest->size.y)) / surface->get_height();
-
- glBindTexture(GL_TEXTURE_2D, gltexture->get_handle());
- intern_draw(request.pos.x, request.pos.y,
- request.pos.x + surfacepartrequest->size.x,
- request.pos.y + surfacepartrequest->size.y,
- uv_left,
- uv_top,
- uv_right,
- uv_bottom,
- 0.0,
- request.alpha,
- request.color,
- Blend(),
- request.drawing_effect);
-}
-
-void
-Renderer::draw_gradient(const DrawingRequest& request)
-{
- const GradientRequest* gradientrequest
- = (GradientRequest*) request.request_data;
- const Color& top = gradientrequest->top;
- const Color& bottom = gradientrequest->bottom;
-
- glDisable(GL_TEXTURE_2D);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glEnableClientState(GL_COLOR_ARRAY);
-
- float vertices[] = {
- 0, 0,
- SCREEN_WIDTH, 0,
- SCREEN_WIDTH, SCREEN_HEIGHT,
- 0, SCREEN_HEIGHT
- };
- glVertexPointer(2, GL_FLOAT, 0, vertices);
-
- float colors[] = {
- top.red, top.green, top.blue, top.alpha,
- top.red, top.green, top.blue, top.alpha,
- bottom.red, bottom.green, bottom.blue, bottom.alpha,
- bottom.red, bottom.green, bottom.blue, bottom.alpha,
- };
- glColorPointer(4, GL_FLOAT, 0, colors);
-
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
- glDisableClientState(GL_COLOR_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-
- glEnable(GL_TEXTURE_2D);
- glColor4f(1, 1, 1, 1);
-}
-
-void
-Renderer::draw_filled_rect(const DrawingRequest& request)
-{
- const FillRectRequest* fillrectrequest
- = (FillRectRequest*) request.request_data;
-
- glDisable(GL_TEXTURE_2D);
- glColor4f(fillrectrequest->color.red, fillrectrequest->color.green,
- fillrectrequest->color.blue, fillrectrequest->color.alpha);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-
- if (fillrectrequest->radius != 0.0f)
- {
- // draw round rect
- // Keep radius in the limits, so that we get a circle instead of
- // just graphic junk
- float radius = std::min(fillrectrequest->radius,
- std::min(fillrectrequest->size.x/2,
- fillrectrequest->size.y/2));
-
- // inner rectangle
- Rect irect(request.pos.x + radius,
- request.pos.y + radius,
- request.pos.x + fillrectrequest->size.x - radius,
- request.pos.y + fillrectrequest->size.y - radius);
-
-
- int n = 8;
- int p = 0;
- float vertices[(n+1) * 4 * 2];
-
- for(int i = 0; i <= n; ++i)
- {
- float x = sinf(i * (M_PI/2) / n) * radius;
- float y = cosf(i * (M_PI/2) / n) * radius;
-
- vertices[p++] = irect.get_left() - x;
- vertices[p++] = irect.get_top() - y;
-
- vertices[p++] = irect.get_right() + x;
- vertices[p++] = irect.get_top() - y;
- }
-
- for(int i = 0; i <= n; ++i)
- {
- float x = cosf(i * (M_PI/2) / n) * radius;
- float y = sinf(i * (M_PI/2) / n) * radius;
-
- vertices[p++] = irect.get_left() - x;
- vertices[p++] = irect.get_bottom() + y;
-
- vertices[p++] = irect.get_right() + x;
- vertices[p++] = irect.get_bottom() + y;
- }
-
- glVertexPointer(2, GL_FLOAT, 0, vertices);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, sizeof(vertices)/sizeof(float)/2);
- }
- else
- {
- float x = request.pos.x;
- float y = request.pos.y;
- float w = fillrectrequest->size.x;
- float h = fillrectrequest->size.y;
-
- float vertices[] = {
- x, y,
- x+w, y,
- x+w, y+h,
- x, y+h
- };
- glVertexPointer(2, GL_FLOAT, 0, vertices);
-
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- }
-
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glEnable(GL_TEXTURE_2D);
- glColor4f(1, 1, 1, 1);
-}
-
-void
-Renderer::draw_inverse_ellipse(const DrawingRequest& request)
-{
- const InverseEllipseRequest* ellipse = (InverseEllipseRequest*)request.request_data;
-
- glDisable(GL_TEXTURE_2D);
- glColor4f(ellipse->color.red, ellipse->color.green,
- ellipse->color.blue, ellipse->color.alpha);
-
- float x = request.pos.x;
- float y = request.pos.y;
- float w = ellipse->size.x/2.0f;
- float h = ellipse->size.y/2.0f;
-
- static const int slices = 16;
- static const int points = (slices+1) * 12;
-
- float vertices[points * 2];
- int p = 0;
-
- // Bottom
- vertices[p++] = SCREEN_WIDTH; vertices[p++] = SCREEN_HEIGHT;
- vertices[p++] = 0; vertices[p++] = SCREEN_HEIGHT;
- vertices[p++] = x; vertices[p++] = y+h;
-
- // Top
- vertices[p++] = SCREEN_WIDTH; vertices[p++] = 0;
- vertices[p++] = 0; vertices[p++] = 0;
- vertices[p++] = x; vertices[p++] = y-h;
-
- // Left
- vertices[p++] = SCREEN_WIDTH; vertices[p++] = 0;
- vertices[p++] = SCREEN_WIDTH; vertices[p++] = SCREEN_HEIGHT;
- vertices[p++] = x+w; vertices[p++] = y;
-
- // Right
- vertices[p++] = 0; vertices[p++] = 0;
- vertices[p++] = 0; vertices[p++] = SCREEN_HEIGHT;
- vertices[p++] = x-w; vertices[p++] = y;
-
- for(int i = 0; i < slices; ++i)
- {
- float ex1 = sinf(M_PI/2 / slices * i) * w;
- float ey1 = cosf(M_PI/2 / slices * i) * h;
-
- float ex2 = sinf(M_PI/2 / slices * (i+1)) * w;
- float ey2 = cosf(M_PI/2 / slices * (i+1)) * h;
-
- // Bottom/Right
- vertices[p++] = SCREEN_WIDTH; vertices[p++] = SCREEN_HEIGHT;
- vertices[p++] = x + ex1; vertices[p++] = y + ey1;
- vertices[p++] = x + ex2; vertices[p++] = y + ey2;
-
- // Top/Left
- vertices[p++] = 0; vertices[p++] = 0;
- vertices[p++] = x - ex1; vertices[p++] = y - ey1;
- vertices[p++] = x - ex2; vertices[p++] = y - ey2;
-
- // Top/Right
- vertices[p++] = SCREEN_WIDTH; vertices[p++] = 0;
- vertices[p++] = x + ex1; vertices[p++] = y - ey1;
- vertices[p++] = x + ex2; vertices[p++] = y - ey2;
-
- // Bottom/Left
- vertices[p++] = 0; vertices[p++] = SCREEN_HEIGHT;
- vertices[p++] = x - ex1; vertices[p++] = y + ey1;
- vertices[p++] = x - ex2; vertices[p++] = y + ey2;
- }
-
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glVertexPointer(2, GL_FLOAT, 0, vertices);
-
- glDrawArrays(GL_TRIANGLES, 0, points);
-
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-
- glEnable(GL_TEXTURE_2D);
- glColor4f(1, 1, 1, 1);
-}
-
-void
-Renderer::do_take_screenshot()
-{
- // [Christoph] TODO: Yes, this method also takes care of the actual disk I/O. Split it?
-
- SDL_Surface *shot_surf;
- // create surface to hold screenshot
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- shot_surf = SDL_CreateRGBSurface(SDL_SWSURFACE, SCREEN_WIDTH, SCREEN_HEIGHT, 24, 0x00FF0000, 0x0000FF00, 0x000000FF, 0);
-#else
- shot_surf = SDL_CreateRGBSurface(SDL_SWSURFACE, SCREEN_WIDTH, SCREEN_HEIGHT, 24, 0x000000FF, 0x0000FF00, 0x00FF0000, 0);
-#endif
- if (!shot_surf) {
- log_warning << "Could not create RGB Surface to contain screenshot" << std::endl;
- return;
- }
-
- // read pixels into array
- char* pixels = new char[3 * SCREEN_WIDTH * SCREEN_HEIGHT];
- if (!pixels) {
- log_warning << "Could not allocate memory to store screenshot" << std::endl;
- SDL_FreeSurface(shot_surf);
- return;
- }
- glReadPixels(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, GL_RGB, GL_UNSIGNED_BYTE, pixels);
-
- // copy array line-by-line
- for (int i = 0; i < SCREEN_HEIGHT; i++) {
- char* src = pixels + (3 * SCREEN_WIDTH * (SCREEN_HEIGHT - i - 1));
- if(SDL_MUSTLOCK(shot_surf))
- {
- SDL_LockSurface(shot_surf);
- }
- char* dst = ((char*)shot_surf->pixels) + i * shot_surf->pitch;
- memcpy(dst, src, 3 * SCREEN_WIDTH);
- if(SDL_MUSTLOCK(shot_surf))
- {
- SDL_UnlockSurface(shot_surf);
- }
- }
-
- // free array
- delete[](pixels);
-
- // save screenshot
- static const std::string writeDir = PHYSFS_getWriteDir();
- static const std::string dirSep = PHYSFS_getDirSeparator();
- static const std::string baseName = "screenshot";
- static const std::string fileExt = ".bmp";
- std::string fullFilename;
- for (int num = 0; num < 1000; num++) {
- std::ostringstream oss;
- oss << baseName;
- oss << std::setw(3) << std::setfill('0') << num;
- oss << fileExt;
- std::string fileName = oss.str();
- fullFilename = writeDir + dirSep + fileName;
- if (!PHYSFS_exists(fileName.c_str())) {
- SDL_SaveBMP(shot_surf, fullFilename.c_str());
- log_debug << "Wrote screenshot to \"" << fullFilename << "\"" << std::endl;
- SDL_FreeSurface(shot_surf);
- return;
- }
- }
- log_warning << "Did not save screenshot, because all files up to \"" << fullFilename << "\" already existed" << std::endl;
- SDL_FreeSurface(shot_surf);
-}
-
-void
-Renderer::flip()
-{
- assert_gl("drawing");
- SDL_GL_SwapBuffers();
-}
-
-void
-Renderer::resize(int w, int h)
-{
- // This causes the screen to go black, which is annoying, but seems
- // unavoidable with SDL at the moment
- SDL_SetVideoMode(w, h, 0, SDL_OPENGL /*| SDL_RESIZABLE*/);
-
- config->window_width = w;
- config->window_height = h;
-
- apply_config();
-}
-
-void
-Renderer::apply_config()
-{
- if (0)
- {
- std::cout << "Applying Config:"
- << "\n Desktop: " << desktop_width << "x" << desktop_height
- << "\n Window: " << config->window_width << "x" << config->window_height
- << "\n FullRes: " << config->fullscreen_width << "x" << config->fullscreen_height
- << "\n Aspect: " << config->aspect_width << ":" << config->aspect_height
- << "\n Magnif: " << config->magnification
- << std::endl;
- }
-
- int w,h;
- float target_aspect = float(desktop_width) / desktop_height;
-
- if (config->aspect_width != 0 && config->aspect_height != 0)
- target_aspect = float(config->aspect_width) / float(config->aspect_height);
-
- float desktop_aspect = 4.0f / 3.0f; // random default fallback guess
-
- if (desktop_width != -1 && desktop_height != -1)
- {
- desktop_aspect = float(desktop_width) / float(desktop_height);
- }
-
- // Get the screen width
- if (config->use_fullscreen)
- {
- w = config->fullscreen_width;
- h = config->fullscreen_height;
- desktop_aspect = float(w) / float(h);
- }
- else
- {
- w = config->window_width;
- h = config->window_height;
- }
-
- if (target_aspect > 1.0f)
- {
- SCREEN_WIDTH = static_cast<int>(w * (target_aspect / desktop_aspect));
- SCREEN_HEIGHT = static_cast<int>(h);
- }
- else
- {
- SCREEN_WIDTH = static_cast<int>(w);
- SCREEN_HEIGHT = static_cast<int>(h * (target_aspect / desktop_aspect));
- }
-
- int max_width = 1600; // FIXME: Maybe 1920 is ok too
- int max_height = 1200;
-
- if (config->magnification == 0.0f) // Magic value that means 'minfill'
- {
- // This scales SCREEN_WIDTH/SCREEN_HEIGHT so that they never excede
- // max_width/max_height
- if (SCREEN_WIDTH > max_width || SCREEN_HEIGHT > max_height)
- {
- float scale1 = float(max_width)/SCREEN_WIDTH;
- float scale2 = float(max_height)/SCREEN_HEIGHT;
- float scale = (scale1 < scale2) ? scale1 : scale2;
- SCREEN_WIDTH = static_cast<int>(SCREEN_WIDTH * scale);
- SCREEN_HEIGHT = static_cast<int>(SCREEN_HEIGHT * scale);
- }
-
- glViewport(0, 0, w, h);
- }
- else
- {
- SCREEN_WIDTH = static_cast<int>(SCREEN_WIDTH / config->magnification);
- SCREEN_HEIGHT = static_cast<int>(SCREEN_HEIGHT / config->magnification);
-
- // This works by adding black borders around the screen to limit
- // SCREEN_WIDTH/SCREEN_HEIGHT to max_width/max_height
- int nw = w;
- int nh = h;
-
- if (SCREEN_WIDTH > max_width)
- {
- nw = static_cast<int>((float) nw * float(max_width)/SCREEN_WIDTH);
- SCREEN_WIDTH = static_cast<int>(max_width);
- }
-
- if (SCREEN_HEIGHT > max_height)
- {
- nh = static_cast<int>((float) nh * float(max_height)/SCREEN_HEIGHT);
- SCREEN_HEIGHT = static_cast<int>(max_height);
- }
-
- // Clear both buffers so that we get a clean black border without junk
- glClear(GL_COLOR_BUFFER_BIT);
- SDL_GL_SwapBuffers();
- glClear(GL_COLOR_BUFFER_BIT);
- SDL_GL_SwapBuffers();
-
- if (0)
- std::cout << (w-nw)/2 << " "
- << (h-nh)/2 << " "
- << nw << "x" << nh << std::endl;
-
- glViewport(std::max(0, (w-nw)/2),
- std::max(0, (h-nh)/2),
- std::min(nw, w),
- std::min(nh, h));
- }
-
- if (0)
- std::cout << " -> " << SCREEN_WIDTH << "x" << SCREEN_HEIGHT << std::endl;
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
-
- glOrtho(0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, -1, 1);
-
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glTranslatef(0, 0, 0);
- check_gl_error("Setting up view matrices");
-}
-
-} // namespace GL
-
-#endif
+++ /dev/null
-// $Id: gl_renderer.hpp 4986 2007-04-16 17:48:28Z matzeb $
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include <config.h>
-
-#ifdef HAVE_OPENGL
-
-#ifndef SUPERTUX_GL_RENDERER_H
-#define SUPERTUX_GL_RENDERER_H
-
-#include "renderer.hpp"
-
-namespace GL
-{
- class Renderer : public ::Renderer
- {
- private:
- int desktop_width;
- int desktop_height;
-
- public:
- Renderer();
- ~Renderer();
-
- void draw_surface(const DrawingRequest& request);
- void draw_surface_part(const DrawingRequest& request);
- void draw_text(const DrawingRequest& request);
- void draw_gradient(const DrawingRequest& request);
- void draw_filled_rect(const DrawingRequest& request);
- void draw_inverse_ellipse(const DrawingRequest& request);
- void do_take_screenshot();
- void flip();
- void resize(int w, int h);
- void apply_config();
- };
-}
-
-#endif
-
-#endif
+++ /dev/null
-// $Id: gl_surface_data.hpp 4063 2006-07-21 21:05:23Z anmaster $
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include <config.h>
-
-#ifdef HAVE_OPENGL
-
-#ifndef __GL_SURFACE_DATA_HPP__
-#define __GL_SURFACE_DATA_HPP__
-
-#include "surface.hpp"
-
-namespace GL
-{
- class SurfaceData
- {
- private:
- const Surface &surface;
- float uv_left;
- float uv_top;
- float uv_right;
- float uv_bottom;
-
- public:
- SurfaceData(const Surface &surface) :
- surface(surface)
- {
- uv_left = (float) surface.get_x() / surface.get_texture()->get_texture_width();
- uv_top = (float) surface.get_y() / surface.get_texture()->get_texture_height();
- uv_right = (float) (surface.get_x() + surface.get_width()) / surface.get_texture()->get_texture_width();
- uv_bottom = (float) (surface.get_y() + surface.get_height()) / surface.get_texture()->get_texture_height();
- }
-
- float get_uv_left() const
- {
- return surface.get_flipx() ? uv_right : uv_left;
- }
-
- float get_uv_top() const
- {
- return uv_top;
- }
-
- float get_uv_right() const
- {
- return surface.get_flipx() ? uv_left : uv_right;
- }
-
- float get_uv_bottom() const
- {
- return uv_bottom;
- }
- };
-}
-
-#endif
-
-#endif
+++ /dev/null
-// $Id: gl_texture.cpp 4063 2006-07-21 21:05:23Z anmaster $
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
-
-#ifdef HAVE_OPENGL
-
-#include "gl_texture.hpp"
-#include "gameconfig.hpp"
-#include "glutil.hpp"
-#include "log.hpp"
-
-#include <assert.h>
-#include <stdexcept>
-
-namespace
-{
- inline bool is_power_of_2(int v)
- {
- return (v & (v-1)) == 0;
- }
-
- inline int next_power_of_two(int val)
- {
- int result = 1;
- while(result < val)
- result *= 2;
- return result;
- }
-}
-
-namespace GL
-{
- Texture::Texture(unsigned int width, unsigned int height)
- {
- assert(is_power_of_2(width));
- assert(is_power_of_2(height));
- texture_width = width;
- texture_height = height;
- image_width = width;
- image_height = height;
-
- assert_gl("before creating texture");
- glGenTextures(1, &handle);
-
- try {
- glBindTexture(GL_TEXTURE_2D, handle);
-
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture_width,
- texture_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
-
- set_texture_params();
- } catch(...) {
- glDeleteTextures(1, &handle);
- throw;
- }
- }
-
- Texture::Texture(SDL_Surface* image)
- {
- texture_width = next_power_of_two(image->w);
- texture_height = next_power_of_two(image->h);
- image_width = image->w;
- image_height = image->h;
-
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- SDL_Surface* convert = SDL_CreateRGBSurface(SDL_SWSURFACE,
- texture_width, texture_height, 32,
- 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff);
-#else
- SDL_Surface* convert = SDL_CreateRGBSurface(SDL_SWSURFACE,
- texture_width, texture_height, 32,
- 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
-#endif
-
- if(convert == 0) {
- throw std::runtime_error("Couldn't create texture: out of memory");
- }
-
- SDL_SetAlpha(image, 0, 0);
- SDL_BlitSurface(image, 0, convert, 0);
-
- assert_gl("before creating texture");
- glGenTextures(1, &handle);
-
- try {
- GLenum sdl_format;
- if(convert->format->BytesPerPixel == 3)
- sdl_format = GL_RGB;
- else if(convert->format->BytesPerPixel == 4)
- sdl_format = GL_RGBA;
- else
- assert(false);
-
- glBindTexture(GL_TEXTURE_2D, handle);
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-#ifdef GL_UNPACK_ROW_LENGTH
- glPixelStorei(GL_UNPACK_ROW_LENGTH, convert->pitch/convert->format->BytesPerPixel);
-#else
- /* OpenGL ES doesn't support UNPACK_ROW_LENGTH, let's hope SDL didn't add
- * padding bytes, otherwise we need some extra code here... */
- assert(convert->pitch == texture_width * convert->format->BytesPerPixel);
-#endif
-
- if(SDL_MUSTLOCK(convert))
- {
- SDL_LockSurface(convert);
- }
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture_width,
- texture_height, 0, sdl_format,
- GL_UNSIGNED_BYTE, convert->pixels);
- if(SDL_MUSTLOCK(convert))
- {
- SDL_UnlockSurface(convert);
- }
-
- assert_gl("creating texture");
-
- set_texture_params();
- } catch(...) {
- glDeleteTextures(1, &handle);
- SDL_FreeSurface(convert);
- throw;
- }
- SDL_FreeSurface(convert);
- }
-
- Texture::~Texture()
- {
- glDeleteTextures(1, &handle);
- }
-
- void
- Texture::set_texture_params()
- {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-#ifdef GL_CLAMP
- /* OpenGL ES doesn't support it */
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
-#endif
-
- assert_gl("set texture params");
- }
-}
-
-#endif
+++ /dev/null
-// $Id: gl_texture.hpp 4063 2006-07-21 21:05:23Z anmaster $
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#ifndef __GL_TEXTURE_HPP__
-#define __GL_TEXTURE_HPP__
-
-#ifdef HAVE_OPENGL
-
-#include <config.h>
-#include <SDL.h>
-
-#include "texture.hpp"
-#include "glutil.hpp"
-
-/**
- * This class is a wrapper around a texture handle. It stores the texture width
- * and height and provides convenience functions for uploading SDL_Surfaces
- * into the texture
- */
-namespace GL
-{
- class Texture : public ::Texture
- {
- protected:
- GLuint handle;
- unsigned int texture_width;
- unsigned int texture_height;
- unsigned int image_width;
- unsigned int image_height;
-
- public:
- Texture(unsigned int width, unsigned int height);
- Texture(SDL_Surface* image);
- ~Texture();
-
- const GLuint &get_handle() const {
- return handle;
- }
-
- void set_handle(GLuint handle) {
- this->handle = handle;
- }
-
- unsigned int get_texture_width() const
- {
- return texture_width;
- }
-
- unsigned int get_texture_height() const
- {
- return texture_height;
- }
-
- unsigned int get_image_width() const
- {
- return image_width;
- }
-
- unsigned int get_image_height() const
- {
- return image_height;
- }
-
- void set_image_width(unsigned int width)
- {
- image_width = width;
- }
-
- void set_image_height(unsigned int height)
- {
- image_height = height;
- }
-
- private:
- void set_texture_params();
- };
-}
-
-#endif
-
-#endif
-
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#ifndef __GLUTIL_HPP__
-#define __GLUTIL_HPP__
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_VIDEO_GLUTIL_HPP
+#define HEADER_SUPERTUX_VIDEO_GLUTIL_HPP
#include <config.h>
#include <sstream>
#include <stdexcept>
-#ifdef MACOSX
-#include <OpenGL/gl.h>
-#include <OpenGL/glext.h>
-#else
-#ifdef GL_VERSION_ES_CM_1_0
-#include <GLES/gl.h>
-#include <GLES/glext.h>
+#if defined(MACOSX)
+# include <OpenGL/gl.h>
+# include <OpenGL/glext.h>
+#elif defined(GL_VERSION_ES_CM_1_0)
+# include <GLES/gl.h>
+# include <GLES/glext.h>
#else
-#include <GL/gl.h>
-#include <GL/glext.h>
-#endif
+# include <GL/gl.h>
+# include <GL/glext.h>
#endif
static inline void check_gl_error(const char* message)
switch(error) {
case GL_INVALID_ENUM:
msg << "INVALID_ENUM: An unacceptable value is specified for an "
- "enumerated argument.";
+ "enumerated argument.";
break;
case GL_INVALID_VALUE:
msg << "INVALID_VALUE: A numeric argument is out of range.";
break;
case GL_INVALID_OPERATION:
msg << "INVALID_OPERATION: The specified operation is not allowed "
- "in the current state.";
+ "in the current state.";
break;
case GL_STACK_OVERFLOW:
msg << "STACK_OVERFLOW: This command would cause a stack overflow.";
break;
case GL_OUT_OF_MEMORY:
msg << "OUT_OF_MEMORY: There is not enough memory left to execute the "
- "command.";
+ "command.";
break;
#ifdef GL_TABLE_TOO_LARGE
case GL_TABLE_TOO_LARGE:
#endif
#endif
+
+/* EOF */
-// $Id: lightmap.hpp 4986 2007-04-16 17:48:28Z matzeb $
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#ifndef SUPERTUX_LIGHTMAP_H
-#define SUPERTUX_LIGHTMAP_H
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_VIDEO_LIGHTMAP_HPP
+#define HEADER_SUPERTUX_VIDEO_LIGHTMAP_HPP
-#include <vector>
-#include <string>
#include <memory>
+#include <string>
+#include <vector>
#include <stdint.h>
#include <SDL_video.h>
-#include "glutil.hpp"
-#include "obstack/obstack.h"
-#include "math/vector.hpp"
#include "math/rect.hpp"
-#include "drawing_request.hpp"
-#include "surface.hpp"
-#include "font.hpp"
-#include "color.hpp"
+#include "math/vector.hpp"
+#include "obstack/obstack.h"
+#include "video/color.hpp"
+#include "video/drawing_request.hpp"
+#include "video/font.hpp"
+#include "video/glutil.hpp"
+#include "video/surface.hpp"
class Texture;
struct DrawingRequest;
#endif
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "renderer.hpp"
+#include "video/renderer.hpp"
Renderer* Renderer::instance_ = 0;
-// $Id: drawing_context.hpp 4986 2007-04-16 17:48:28Z matzeb $
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef SUPERTUX_RENDERER_H
-#define SUPERTUX_RENDERER_H
+#ifndef HEADER_SUPERTUX_VIDEO_RENDERER_HPP
+#define HEADER_SUPERTUX_VIDEO_RENDERER_HPP
-#include <vector>
-#include <string>
#include <memory>
+#include <string>
+#include <vector>
-#include <stdint.h>
-#include <assert.h>
#include <SDL_video.h>
+#include <assert.h>
+#include <stdint.h>
-#include "glutil.hpp"
-#include "obstack/obstack.h"
-#include "math/vector.hpp"
#include "math/rect.hpp"
-#include "surface.hpp"
-#include "font.hpp"
-#include "color.hpp"
+#include "math/vector.hpp"
+#include "obstack/obstack.h"
+#include "video/color.hpp"
+#include "video/font.hpp"
+#include "video/glutil.hpp"
+#include "video/surface.hpp"
class Surface;
class Texture;
#endif
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include <iostream>
+
+#include "video/sdl/sdl_lightmap.hpp"
+#include "video/sdl/sdl_surface_data.hpp"
+#include "video/sdl/sdl_texture.hpp"
+
+SDLLightmap::SDLLightmap()
+{
+ screen = SDL_GetVideoSurface();
+
+ //float xfactor = 1.0f; // FIXME: (float) config->screenwidth / SCREEN_WIDTH;
+ //float yfactor = 1.0f; // FIXME: (float) config->screenheight / SCREEN_HEIGHT;
+
+ numerator = 1;
+ denominator = 1;
+
+ /* FIXME:
+ if(xfactor < yfactor)
+ {
+ numerator = config->screenwidth;
+ denominator = SCREEN_WIDTH;
+ }
+ else
+ {
+ numerator = config->screenheight;
+ denominator = SCREEN_HEIGHT;
+ }
+ */
+
+ LIGHTMAP_DIV = 8 * numerator / denominator;
+
+ width = screen->w / LIGHTMAP_DIV;
+ height = screen->h / LIGHTMAP_DIV;
+
+ red_channel = (Uint8 *)malloc(width * height * sizeof(Uint8));
+ green_channel = (Uint8 *)malloc(width * height * sizeof(Uint8));
+ blue_channel = (Uint8 *)malloc(width * height * sizeof(Uint8));
+}
+
+SDLLightmap::~SDLLightmap()
+{
+ free(red_channel);
+ free(green_channel);
+ free(blue_channel);
+}
+
+void
+SDLLightmap::start_draw(const Color &ambient_color)
+{
+ memset(red_channel, (Uint8) (ambient_color.red * 255), width * height * sizeof(Uint8));
+ memset(green_channel, (Uint8) (ambient_color.green * 255), width * height * sizeof(Uint8));
+ memset(blue_channel, (Uint8) (ambient_color.blue * 255), width * height * sizeof(Uint8));
+}
+
+void
+SDLLightmap::end_draw()
+{
+}
+
+//#define BILINEAR
+
+#ifdef BILINEAR
+namespace {
+
+void merge(Uint8 color[3], Uint8 color0[3], Uint8 color1[3], int rem, int total)
+{
+ color[0] = (color0[0] * (total - rem) + color1[0] * rem) / total;
+ color[1] = (color0[1] * (total - rem) + color1[1] * rem) / total;
+ color[2] = (color0[2] * (total - rem) + color1[2] * rem) / total;
+}
+
+} // namespace
+#endif
+
+void
+SDLLightmap::do_draw()
+{
+ // FIXME: This is really slow
+ if(LIGHTMAP_DIV == 1)
+ {
+ int bpp = screen->format->BytesPerPixel;
+ if(SDL_MUSTLOCK(screen))
+ {
+ SDL_LockSurface(screen);
+ }
+ Uint8 *pixel = (Uint8 *) screen->pixels;
+ int loc = 0;
+ for(int y = 0;y < height;y++) {
+ for(int x = 0;x < width;x++, pixel += bpp, loc++) {
+ if(red_channel[loc] == 0xff && green_channel[loc] == 0xff && blue_channel[loc] == 0xff)
+ {
+ continue;
+ }
+ Uint32 mapped = 0;
+ switch(bpp) {
+ case 1:
+ mapped = *pixel;
+ break;
+ case 2:
+ mapped = *(Uint16 *)pixel;
+ break;
+ case 3:
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ mapped |= pixel[0] << 16;
+ mapped |= pixel[1] << 8;
+ mapped |= pixel[2] << 0;
+#else
+ mapped |= pixel[0] << 0;
+ mapped |= pixel[1] << 8;
+ mapped |= pixel[2] << 16;
+#endif
+ break;
+ case 4:
+ mapped = *(Uint32 *)pixel;
+ break;
+ }
+ Uint8 red, green, blue, alpha;
+ SDL_GetRGBA(mapped, screen->format, &red, &green, &blue, &alpha);
+ red = (red * red_channel[loc]) >> 8;
+ green = (green * green_channel[loc]) >> 8;
+ blue = (blue * blue_channel[loc]) >> 8;
+ mapped = SDL_MapRGBA(screen->format, red, green, blue, alpha);
+ switch(bpp) {
+ case 1:
+ *pixel = mapped;
+ break;
+ case 2:
+ *(Uint16 *)pixel = mapped;
+ break;
+ case 3:
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ pixel[0] = (mapped >> 16) & 0xff;
+ pixel[1] = (mapped >> 8) & 0xff;
+ pixel[2] = (mapped >> 0) & 0xff;
+#else
+ pixel[0] = (mapped >> 0) & 0xff;
+ pixel[1] = (mapped >> 8) & 0xff;
+ pixel[2] = (mapped >> 16) & 0xff;
+#endif
+ break;
+ case 4:
+ *(Uint32 *)pixel = mapped;
+ break;
+ }
+ }
+ pixel += screen->pitch - width * bpp;
+ }
+ if(SDL_MUSTLOCK(screen))
+ {
+ SDL_UnlockSurface(screen);
+ }
+ }
+ else
+ {
+ int bpp = screen->format->BytesPerPixel;
+ if(SDL_MUSTLOCK(screen))
+ {
+ SDL_LockSurface(screen);
+ }
+ Uint8 *div_pixel = (Uint8 *) screen->pixels;
+ int loc = 0;
+ for(int y = 0;y < height;y++) {
+ for(int x = 0;x < width;x++, div_pixel += bpp * LIGHTMAP_DIV, loc++) {
+ if(red_channel[loc] == 0xff && green_channel[loc] == 0xff && blue_channel[loc] == 0xff)
+ {
+ continue;
+ }
+ Uint8 *pixel = div_pixel;
+ for(int div_y = 0;div_y < LIGHTMAP_DIV;div_y++) {
+ for(int div_x = 0;div_x < LIGHTMAP_DIV;pixel += bpp, div_x++) {
+ Uint32 mapped = 0;
+ switch(bpp) {
+ case 1:
+ mapped = *pixel;
+ break;
+ case 2:
+ mapped = *(Uint16 *)pixel;
+ break;
+ case 3:
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ mapped |= pixel[0] << 16;
+ mapped |= pixel[1] << 8;
+ mapped |= pixel[2] << 0;
+#else
+ mapped |= pixel[0] << 0;
+ mapped |= pixel[1] << 8;
+ mapped |= pixel[2] << 16;
+#endif
+ break;
+ case 4:
+ mapped = *(Uint32 *)pixel;
+ break;
+ }
+ Uint8 red, green, blue, alpha;
+ SDL_GetRGBA(mapped, screen->format, &red, &green, &blue, &alpha);
+
+#ifdef BILINEAR
+ int xinc = (x + 1 != width ? 1 : 0);
+ int yinc = (y + 1 != height ? width : 0);
+ Uint8 color00[3], color01[3], color10[3], color11[3];
+ {
+ color00[0] = red_channel[loc];
+ color00[1] = green_channel[loc];
+ color00[2] = blue_channel[loc];
+ }
+ {
+ color01[0] = red_channel[loc + xinc];
+ color01[1] = green_channel[loc + xinc];
+ color01[2] = blue_channel[loc + xinc];
+ }
+ {
+ color10[0] = red_channel[loc + yinc];
+ color10[1] = green_channel[loc + yinc];
+ color10[2] = blue_channel[loc + yinc];
+ }
+ {
+ color11[0] = red_channel[loc + yinc + xinc];
+ color11[1] = green_channel[loc + yinc + xinc];
+ color11[2] = blue_channel[loc + yinc + xinc];
+ }
+ Uint8 color0[3], color1[3], color[3];
+ merge(color0, color00, color01, div_x, LIGHTMAP_DIV);
+ merge(color1, color10, color11, div_x, LIGHTMAP_DIV);
+ merge(color, color0, color1, div_y, LIGHTMAP_DIV);
+ red = (red * color[0]) >> 8;
+ green = (green * color[1]) >> 8;
+ blue = (blue * color[2]) >> 8;
+#else
+ red = (red * red_channel[loc]) >> 8;
+ green = (green * green_channel[loc]) >> 8;
+ blue = (blue * blue_channel[loc]) >> 8;
+#endif
+
+ mapped = SDL_MapRGBA(screen->format, red, green, blue, alpha);
+ switch(bpp) {
+ case 1:
+ *pixel = mapped;
+ break;
+ case 2:
+ *(Uint16 *)pixel = mapped;
+ break;
+ case 3:
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ pixel[0] = (mapped >> 16) & 0xff;
+ pixel[1] = (mapped >> 8) & 0xff;
+ pixel[2] = (mapped >> 0) & 0xff;
+#else
+ pixel[0] = (mapped >> 0) & 0xff;
+ pixel[1] = (mapped >> 8) & 0xff;
+ pixel[2] = (mapped >> 16) & 0xff;
+#endif
+ break;
+ case 4:
+ *(Uint32 *)pixel = mapped;
+ break;
+ }
+ }
+ pixel += screen->pitch - LIGHTMAP_DIV * bpp;
+ }
+ }
+ div_pixel += (screen->pitch - width * bpp) * LIGHTMAP_DIV;
+ }
+ if(SDL_MUSTLOCK(screen))
+ {
+ SDL_UnlockSurface(screen);
+ }
+ }
+}
+
+void
+SDLLightmap::light_blit(SDL_Surface *src, SDL_Rect *src_rect, int dstx, int dsty)
+{
+ dstx /= LIGHTMAP_DIV;
+ dsty /= LIGHTMAP_DIV;
+ int srcx = src_rect->x / LIGHTMAP_DIV;
+ int srcy = src_rect->y / LIGHTMAP_DIV;
+ int blit_width = src_rect->w / LIGHTMAP_DIV;
+ int blit_height = src_rect->h / LIGHTMAP_DIV;
+ int bpp = src->format->BytesPerPixel;
+ if(SDL_MUSTLOCK(src))
+ {
+ SDL_LockSurface(src);
+ }
+ Uint8 *pixel = (Uint8 *) src->pixels + srcy * src->pitch + srcx * bpp;
+ int loc = dsty * width + dstx;
+ for(int y = 0;y < blit_height;y++) {
+ for(int x = 0;x < blit_width;x++, pixel += bpp * LIGHTMAP_DIV, loc++) {
+ if(x + dstx < 0 || y + dsty < 0 || x + dstx >= width || y + dsty >= height)
+ {
+ continue;
+ }
+ if(red_channel[loc] == 0xff && green_channel[loc] == 0xff && blue_channel[loc] == 0xff)
+ {
+ continue;
+ }
+
+ Uint32 mapped = 0;
+ switch(bpp) {
+ case 1:
+ mapped = *pixel;
+ break;
+ case 2:
+ mapped = *(Uint16 *)pixel;
+ break;
+ case 3:
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ mapped |= pixel[0] << 16;
+ mapped |= pixel[1] << 8;
+ mapped |= pixel[2] << 0;
+#else
+ mapped |= pixel[0] << 0;
+ mapped |= pixel[1] << 8;
+ mapped |= pixel[2] << 16;
+#endif
+ break;
+ case 4:
+ mapped = *(Uint32 *)pixel;
+ break;
+ }
+ Uint8 red, green, blue, alpha;
+ SDL_GetRGBA(mapped, src->format, &red, &green, &blue, &alpha);
+
+ if(red != 0)
+ {
+ int redsum = red_channel[loc] + (red * alpha >> 8);
+ red_channel[loc] = redsum & ~0xff ? 0xff : redsum;
+ }
+ if(green != 0)
+ {
+ int greensum = green_channel[loc] + (green * alpha >> 8);
+ green_channel[loc] = greensum & ~0xff ? 0xff : greensum;
+ }
+ if(blue != 0)
+ {
+ int bluesum = blue_channel[loc] + (blue * alpha >> 8);
+ blue_channel[loc] = bluesum & ~0xff ? 0xff : bluesum;
+ }
+ }
+ pixel += (src->pitch - blit_width * bpp) * LIGHTMAP_DIV;
+ loc += width - blit_width;
+ }
+ if(SDL_MUSTLOCK(src))
+ {
+ SDL_UnlockSurface(src);
+ }
+}
+
+/*void Lightmap::light_blit(SDL_Surface *src, SDL_Rect *src_rect, int dstx, int dsty)
+ {
+ int bpp = src->format->BytesPerPixel;
+ if(SDL_MUSTLOCK(src))
+ {
+ SDL_LockSurface(src);
+ }
+ Uint8 *pixel = (Uint8 *) src->pixels + src_rect->y * src->pitch + src_rect->x * bpp;
+ int loc = dsty * width + dstx;
+ for(int y = 0;y < src_rect->h;y++) {
+ for(int x = 0;x < src_rect->w;x++, pixel += bpp, loc++) {
+ if(x + dstx < 0 || y + dsty < 0 || x + dstx >= width || y + dsty >= height)
+ {
+ continue;
+ }
+ if(red_channel[loc] == 0xff && green_channel[loc] == 0xff && blue_channel[loc] == 0xff)
+ {
+ continue;
+ }
+
+ Uint32 mapped = 0;
+ switch(bpp) {
+ case 1:
+ mapped = *pixel;
+ break;
+ case 2:
+ mapped = *(Uint16 *)pixel;
+ break;
+ case 3:
+ #if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ mapped |= pixel[0] << 16;
+ mapped |= pixel[1] << 8;
+ mapped |= pixel[2] << 0;
+ #else
+ mapped |= pixel[0] << 0;
+ mapped |= pixel[1] << 8;
+ mapped |= pixel[2] << 16;
+ #endif
+ break;
+ case 4:
+ mapped = *(Uint32 *)pixel;
+ break;
+ }
+ Uint8 red, green, blue, alpha;
+ SDL_GetRGBA(mapped, src->format, &red, &green, &blue, &alpha);
+
+ if(red != 0)
+ {
+ int redsum = red_channel[loc] + (red * alpha >> 8);
+ red_channel[loc] = redsum & ~0xff ? 0xff : redsum;
+ }
+ if(green != 0)
+ {
+ int greensum = green_channel[loc] + (green * alpha >> 8);
+ green_channel[loc] = greensum & ~0xff ? 0xff : greensum;
+ }
+ if(blue != 0)
+ {
+ int bluesum = blue_channel[loc] + (blue * alpha >> 8);
+ blue_channel[loc] = bluesum & ~0xff ? 0xff : bluesum;
+ }
+ }
+ pixel += src->pitch - src_rect->w * bpp;
+ loc += width - src_rect->w;
+ }
+ if(SDL_MUSTLOCK(src))
+ {
+ SDL_UnlockSurface(src);
+ }
+ }*/
+
+void
+SDLLightmap::draw_surface(const DrawingRequest& request)
+{
+ if((request.color.red == 0.0 && request.color.green == 0.0 && request.color.blue == 0.0) || request.color.alpha == 0.0 || request.alpha == 0.0)
+ {
+ return;
+ }
+ //FIXME: support parameters request.alpha, request.angle, request.blend
+
+ const Surface* surface = (const Surface*) request.request_data;
+ SDLTexture *sdltexture = dynamic_cast<SDLTexture *>(surface->get_texture());
+ SDLSurfaceData *surface_data = reinterpret_cast<SDLSurfaceData *>(surface->get_surface_data());
+
+ DrawingEffect effect = request.drawing_effect;
+ if (surface->get_flipx()) effect = HORIZONTAL_FLIP;
+
+ SDL_Surface *transform = sdltexture->get_transform(request.color, effect);
+
+ // get and check SDL_Surface
+ if (transform == 0) {
+ std::cerr << "Warning: Tried to draw NULL surface, skipped draw" << std::endl;
+ return;
+ }
+
+ SDL_Rect *src_rect = surface_data->get_src_rect(effect);
+ int dstx = (int) request.pos.x * numerator / denominator;
+ int dsty = (int) request.pos.y * numerator / denominator;
+ light_blit(transform, src_rect, dstx, dsty);
+}
+
+void
+SDLLightmap::draw_surface_part(const DrawingRequest& request)
+{
+ const SurfacePartRequest* surfacepartrequest
+ = (SurfacePartRequest*) request.request_data;
+
+ const Surface* surface = surfacepartrequest->surface;
+ SDLTexture *sdltexture = dynamic_cast<SDLTexture *>(surface->get_texture());
+
+ DrawingEffect effect = request.drawing_effect;
+ if (surface->get_flipx()) effect = HORIZONTAL_FLIP;
+
+ SDL_Surface *transform = sdltexture->get_transform(Color(1.0, 1.0, 1.0), effect);
+
+ // get and check SDL_Surface
+ if (transform == 0) {
+ std::cerr << "Warning: Tried to draw NULL surface, skipped draw" << std::endl;
+ return;
+ }
+
+ int ox, oy;
+ if (effect == HORIZONTAL_FLIP)
+ {
+ ox = sdltexture->get_texture_width() - surface->get_x() - (int) surfacepartrequest->size.x;
+ }
+ else
+ {
+ ox = surface->get_x();
+ }
+ if (effect == VERTICAL_FLIP)
+ {
+ oy = sdltexture->get_texture_height() - surface->get_y() - (int) surfacepartrequest->size.y;
+ }
+ else
+ {
+ oy = surface->get_y();
+ }
+
+ SDL_Rect src_rect;
+ src_rect.x = (ox + (int) surfacepartrequest->source.x) * numerator / denominator;
+ src_rect.y = (oy + (int) surfacepartrequest->source.y) * numerator / denominator;
+ src_rect.w = (int) surfacepartrequest->size.x * numerator / denominator;
+ src_rect.h = (int) surfacepartrequest->size.y * numerator / denominator;
+ int dstx = (int) request.pos.x * numerator / denominator;
+ int dsty = (int) request.pos.y * numerator / denominator;
+ light_blit(transform, &src_rect, dstx, dsty);
+}
+
+void
+SDLLightmap::draw_gradient(const DrawingRequest& request)
+{
+ const GradientRequest* gradientrequest
+ = (GradientRequest*) request.request_data;
+ const Color& top = gradientrequest->top;
+ const Color& bottom = gradientrequest->bottom;
+
+ int loc = 0;
+ for(int y = 0;y < height;++y)
+ {
+ Uint8 red = (Uint8)((((float)(top.red-bottom.red)/(0-height)) * y + top.red) * 255);
+ Uint8 green = (Uint8)((((float)(top.green-bottom.green)/(0-height)) * y + top.green) * 255);
+ Uint8 blue = (Uint8)((((float)(top.blue-bottom.blue)/(0-height)) * y + top.blue) * 255);
+ Uint8 alpha = (Uint8)((((float)(top.alpha-bottom.alpha)/(0-height)) * y + top.alpha) * 255);
+ for(int x = 0;x < width;x++, loc++) {
+ if(red != 0)
+ {
+ int redsum = red_channel[loc] + (red * alpha >> 8);
+ red_channel[loc] = redsum & ~0xff ? 0xff : redsum;
+ }
+ if(green != 0)
+ {
+ int greensum = green_channel[loc] + (green * alpha >> 8);
+ green_channel[loc] = greensum & ~0xff ? 0xff : greensum;
+ }
+ if(blue != 0)
+ {
+ int bluesum = blue_channel[loc] + (blue * alpha >> 8);
+ blue_channel[loc] = bluesum & ~0xff ? 0xff : bluesum;
+ }
+ }
+ }
+}
+
+void
+SDLLightmap::draw_filled_rect(const DrawingRequest& request)
+{
+ const FillRectRequest* fillrectrequest
+ = (FillRectRequest*) request.request_data;
+
+ int rect_x = (int) (request.pos.x * width / SCREEN_WIDTH);
+ int rect_y = (int) (request.pos.y * height / SCREEN_HEIGHT);
+ int rect_w = (int) (fillrectrequest->size.x * width / SCREEN_WIDTH);
+ int rect_h = (int) (fillrectrequest->size.y * height / SCREEN_HEIGHT);
+ Uint8 red = (Uint8) (fillrectrequest->color.red * fillrectrequest->color.alpha * 255);
+ Uint8 green = (Uint8) (fillrectrequest->color.green * fillrectrequest->color.alpha * 255);
+ Uint8 blue = (Uint8) (fillrectrequest->color.blue * fillrectrequest->color.alpha * 255);
+ if(red == 0 && green == 0 && blue == 0)
+ {
+ return;
+ }
+ for(int y = rect_y;y < rect_y + rect_h;y++) {
+ for(int x = rect_x;x < rect_x + rect_w;x++) {
+ int loc = y * width + x;
+ if(red != 0)
+ {
+ int redsum = red_channel[loc] + red;
+ red_channel[loc] = redsum & ~0xff ? 0xff : redsum;
+ }
+ if(green != 0)
+ {
+ int greensum = green_channel[loc] + green;
+ green_channel[loc] = greensum & ~0xff ? 0xff : greensum;
+ }
+ if(blue != 0)
+ {
+ int bluesum = blue_channel[loc] + blue;
+ blue_channel[loc] = bluesum & ~0xff ? 0xff : bluesum;
+ }
+ }
+ }
+}
+
+void
+SDLLightmap::get_light(const DrawingRequest& request) const
+{
+ const GetLightRequest* getlightrequest
+ = (GetLightRequest*) request.request_data;
+
+ int x = (int) (request.pos.x * width / SCREEN_WIDTH);
+ int y = (int) (request.pos.y * height / SCREEN_HEIGHT);
+ int loc = y * width + x;
+ *(getlightrequest->color_ptr) = Color(((float)red_channel[loc])/255, ((float)green_channel[loc])/255, ((float)blue_channel[loc])/255);
+}
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_VIDEO_SDL_LIGHTMAP_HPP
+#define HEADER_SUPERTUX_VIDEO_SDL_LIGHTMAP_HPP
+
+#include "video/lightmap.hpp"
+
+class Color;
+struct DrawingRequest;
+
+class SDLLightmap : public Lightmap
+{
+public:
+ SDLLightmap();
+ ~SDLLightmap();
+
+ void start_draw(const Color &ambient_color);
+ void end_draw();
+ void do_draw();
+ void draw_surface(const DrawingRequest& request);
+ void draw_surface_part(const DrawingRequest& request);
+ void draw_text(const DrawingRequest& request);
+ void draw_gradient(const DrawingRequest& request);
+ void draw_filled_rect(const DrawingRequest& request);
+ void get_light(const DrawingRequest& request) const;
+
+private:
+ SDL_Surface* screen;
+ Uint8 *red_channel;
+ Uint8 *blue_channel;
+ Uint8 *green_channel;
+ int width, height;
+ int numerator, denominator;
+ int LIGHTMAP_DIV;
+
+ void light_blit(SDL_Surface *src, SDL_Rect *src_rect, int dstx, int dsty);
+};
+
+#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include "video/sdl/sdl_renderer.hpp"
+
+#include <iomanip>
+#include <iostream>
+#include <physfs.h>
+
+#include "video/drawing_request.hpp"
+#include "video/sdl/sdl_surface_data.hpp"
+#include "video/sdl/sdl_texture.hpp"
+
+namespace {
+
+SDL_Surface *apply_alpha(SDL_Surface *src, float alpha_factor)
+{
+ // FIXME: This is really slow
+ assert(src->format->Amask);
+ int alpha = (int) (alpha_factor * 256);
+ SDL_Surface *dst = SDL_CreateRGBSurface(src->flags, src->w, src->h, src->format->BitsPerPixel, src->format->Rmask, src->format->Gmask, src->format->Bmask, src->format->Amask);
+ int bpp = dst->format->BytesPerPixel;
+ if(SDL_MUSTLOCK(src))
+ {
+ SDL_LockSurface(src);
+ }
+ if(SDL_MUSTLOCK(dst))
+ {
+ SDL_LockSurface(dst);
+ }
+ for(int y = 0;y < dst->h;y++) {
+ for(int x = 0;x < dst->w;x++) {
+ Uint8 *srcpixel = (Uint8 *) src->pixels + y * src->pitch + x * bpp;
+ Uint8 *dstpixel = (Uint8 *) dst->pixels + y * dst->pitch + x * bpp;
+ Uint32 mapped = 0;
+ switch(bpp) {
+ case 1:
+ mapped = *srcpixel;
+ break;
+ case 2:
+ mapped = *(Uint16 *)srcpixel;
+ break;
+ case 3:
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ mapped |= srcpixel[0] << 16;
+ mapped |= srcpixel[1] << 8;
+ mapped |= srcpixel[2] << 0;
+#else
+ mapped |= srcpixel[0] << 0;
+ mapped |= srcpixel[1] << 8;
+ mapped |= srcpixel[2] << 16;
+#endif
+ break;
+ case 4:
+ mapped = *(Uint32 *)srcpixel;
+ break;
+ }
+ Uint8 r, g, b, a;
+ SDL_GetRGBA(mapped, src->format, &r, &g, &b, &a);
+ mapped = SDL_MapRGBA(dst->format, r, g, b, (a * alpha) >> 8);
+ switch(bpp) {
+ case 1:
+ *dstpixel = mapped;
+ break;
+ case 2:
+ *(Uint16 *)dstpixel = mapped;
+ break;
+ case 3:
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ dstpixel[0] = (mapped >> 16) & 0xff;
+ dstpixel[1] = (mapped >> 8) & 0xff;
+ dstpixel[2] = (mapped >> 0) & 0xff;
+#else
+ dstpixel[0] = (mapped >> 0) & 0xff;
+ dstpixel[1] = (mapped >> 8) & 0xff;
+ dstpixel[2] = (mapped >> 16) & 0xff;
+#endif
+ break;
+ case 4:
+ *(Uint32 *)dstpixel = mapped;
+ break;
+ }
+ }
+ }
+ if(SDL_MUSTLOCK(dst))
+ {
+ SDL_UnlockSurface(dst);
+ }
+ if(SDL_MUSTLOCK(src))
+ {
+ SDL_UnlockSurface(src);
+ }
+ return dst;
+}
+
+} // namespace
+
+SDLRenderer::SDLRenderer()
+{
+ ::Renderer::instance_ = this;
+
+ const SDL_VideoInfo *info = SDL_GetVideoInfo();
+ log_info << "Hardware surfaces are " << (info->hw_available ? "" : "not ") << "available." << std::endl;
+ log_info << "Hardware to hardware blits are " << (info->blit_hw ? "" : "not ") << "accelerated." << std::endl;
+ log_info << "Hardware to hardware blits with colorkey are " << (info->blit_hw_CC ? "" : "not ") << "accelerated." << std::endl;
+ log_info << "Hardware to hardware blits with alpha are " << (info->blit_hw_A ? "" : "not ") << "accelerated." << std::endl;
+ log_info << "Software to hardware blits are " << (info->blit_sw ? "" : "not ") << "accelerated." << std::endl;
+ log_info << "Software to hardware blits with colorkey are " << (info->blit_sw_CC ? "" : "not ") << "accelerated." << std::endl;
+ log_info << "Software to hardware blits with alpha are " << (info->blit_sw_A ? "" : "not ") << "accelerated." << std::endl;
+ log_info << "Color fills are " << (info->blit_fill ? "" : "not ") << "accelerated." << std::endl;
+
+ int flags = SDL_SWSURFACE | SDL_ANYFORMAT;
+ if(g_config->use_fullscreen)
+ flags |= SDL_FULLSCREEN;
+
+ int width = 800; //FIXME: config->screenwidth;
+ int height = 600; //FIXME: config->screenheight;
+
+ screen = SDL_SetVideoMode(width, height, 0, flags);
+ if(screen == 0) {
+ std::stringstream msg;
+ msg << "Couldn't set video mode (" << width << "x" << height
+ << "): " << SDL_GetError();
+ throw std::runtime_error(msg.str());
+ }
+
+ numerator = 1;
+ denominator = 1;
+ /* FIXME:
+ float xfactor = (float) config->screenwidth / SCREEN_WIDTH;
+ float yfactor = (float) config->screenheight / SCREEN_HEIGHT;
+ if(xfactor < yfactor)
+ {
+ numerator = config->screenwidth;
+ denominator = SCREEN_WIDTH;
+ }
+ else
+ {
+ numerator = config->screenheight;
+ denominator = SCREEN_HEIGHT;
+ }
+ */
+ if(texture_manager == 0)
+ texture_manager = new TextureManager();
+}
+
+SDLRenderer::~SDLRenderer()
+{
+}
+
+void
+SDLRenderer::draw_surface(const DrawingRequest& request)
+{
+ //FIXME: support parameters request.alpha, request.angle, request.blend
+ const Surface* surface = (const Surface*) request.request_data;
+ SDLTexture *sdltexture = dynamic_cast<SDLTexture *>(surface->get_texture());
+ SDLSurfaceData *surface_data = reinterpret_cast<SDLSurfaceData *>(surface->get_surface_data());
+
+ DrawingEffect effect = request.drawing_effect;
+ if (surface->get_flipx()) effect = HORIZONTAL_FLIP;
+
+ SDL_Surface *transform = sdltexture->get_transform(request.color, effect);
+
+ // get and check SDL_Surface
+ if (transform == 0) {
+ std::cerr << "Warning: Tried to draw NULL surface, skipped draw" << std::endl;
+ return;
+ }
+
+ SDL_Rect *src_rect = surface_data->get_src_rect(effect);
+ SDL_Rect dst_rect;
+ dst_rect.x = (int) request.pos.x * numerator / denominator;
+ dst_rect.y = (int) request.pos.y * numerator / denominator;
+
+ Uint8 alpha = 0;
+ if(request.alpha != 1.0)
+ {
+ if(!transform->format->Amask)
+ {
+ if(transform->flags & SDL_SRCALPHA)
+ {
+ alpha = transform->format->alpha;
+ }
+ else
+ {
+ alpha = 255;
+ }
+ SDL_SetAlpha(transform, SDL_SRCALPHA, (Uint8) (request.alpha * alpha));
+ }
+ /*else
+ {
+ transform = apply_alpha(transform, request.alpha);
+ }*/
+ }
+
+ SDL_BlitSurface(transform, src_rect, screen, &dst_rect);
+
+ if(request.alpha != 1.0)
+ {
+ if(!transform->format->Amask)
+ {
+ if(alpha == 255)
+ {
+ SDL_SetAlpha(transform, SDL_RLEACCEL, 0);
+ }
+ else
+ {
+ SDL_SetAlpha(transform, SDL_SRCALPHA | SDL_RLEACCEL, alpha);
+ }
+ }
+ /*else
+ {
+ SDL_FreeSurface(transform);
+ }*/
+ }
+}
+
+void
+SDLRenderer::draw_surface_part(const DrawingRequest& request)
+{
+ const SurfacePartRequest* surfacepartrequest
+ = (SurfacePartRequest*) request.request_data;
+
+ const Surface* surface = surfacepartrequest->surface;
+ SDLTexture *sdltexture = dynamic_cast<SDLTexture*>(surface->get_texture());
+
+ DrawingEffect effect = request.drawing_effect;
+ if (surface->get_flipx()) effect = HORIZONTAL_FLIP;
+
+ SDL_Surface *transform = sdltexture->get_transform(request.color, effect);
+
+ // get and check SDL_Surface
+ if (transform == 0) {
+ std::cerr << "Warning: Tried to draw NULL surface, skipped draw" << std::endl;
+ return;
+ }
+
+ int ox, oy;
+ if (effect == HORIZONTAL_FLIP)
+ {
+ ox = sdltexture->get_texture_width() - surface->get_x() - (int) surfacepartrequest->size.x;
+ }
+ else
+ {
+ ox = surface->get_x();
+ }
+ if (effect == VERTICAL_FLIP)
+ {
+ oy = sdltexture->get_texture_height() - surface->get_y() - (int) surfacepartrequest->size.y;
+ }
+ else
+ {
+ oy = surface->get_y();
+ }
+
+ SDL_Rect src_rect;
+ src_rect.x = (ox + (int) surfacepartrequest->source.x) * numerator / denominator;
+ src_rect.y = (oy + (int) surfacepartrequest->source.y) * numerator / denominator;
+ src_rect.w = (int) surfacepartrequest->size.x * numerator / denominator;
+ src_rect.h = (int) surfacepartrequest->size.y * numerator / denominator;
+
+ SDL_Rect dst_rect;
+ dst_rect.x = (int) request.pos.x * numerator / denominator;
+ dst_rect.y = (int) request.pos.y * numerator / denominator;
+
+ Uint8 alpha = 0;
+ if(request.alpha != 1.0)
+ {
+ if(!transform->format->Amask)
+ {
+ if(transform->flags & SDL_SRCALPHA)
+ {
+ alpha = transform->format->alpha;
+ }
+ else
+ {
+ alpha = 255;
+ }
+ SDL_SetAlpha(transform, SDL_SRCALPHA, (Uint8) (request.alpha * alpha));
+ }
+ /*else
+ {
+ transform = apply_alpha(transform, request.alpha);
+ }*/
+ }
+
+ SDL_BlitSurface(transform, &src_rect, screen, &dst_rect);
+
+ if(request.alpha != 1.0)
+ {
+ if(!transform->format->Amask)
+ {
+ if(alpha == 255)
+ {
+ SDL_SetAlpha(transform, SDL_RLEACCEL, 0);
+ }
+ else
+ {
+ SDL_SetAlpha(transform, SDL_SRCALPHA | SDL_RLEACCEL, alpha);
+ }
+ }
+ /*else
+ {
+ SDL_FreeSurface(transform);
+ }*/
+ }
+}
+
+void
+SDLRenderer::draw_gradient(const DrawingRequest& request)
+{
+ const GradientRequest* gradientrequest
+ = (GradientRequest*) request.request_data;
+ const Color& top = gradientrequest->top;
+ const Color& bottom = gradientrequest->bottom;
+
+ for(int y = 0;y < screen->h;++y)
+ {
+ Uint8 r = (Uint8)((((float)(top.red-bottom.red)/(0-screen->h)) * y + top.red) * 255);
+ Uint8 g = (Uint8)((((float)(top.green-bottom.green)/(0-screen->h)) * y + top.green) * 255);
+ Uint8 b = (Uint8)((((float)(top.blue-bottom.blue)/(0-screen->h)) * y + top.blue) * 255);
+ Uint8 a = (Uint8)((((float)(top.alpha-bottom.alpha)/(0-screen->h)) * y + top.alpha) * 255);
+ Uint32 color = SDL_MapRGB(screen->format, r, g, b);
+
+ SDL_Rect rect;
+ rect.x = 0;
+ rect.y = y;
+ rect.w = screen->w;
+ rect.h = 1;
+
+ if(a == SDL_ALPHA_OPAQUE) {
+ SDL_FillRect(screen, &rect, color);
+ } else if(a != SDL_ALPHA_TRANSPARENT) {
+ SDL_Surface *temp = SDL_CreateRGBSurface(screen->flags, rect.w, rect.h, screen->format->BitsPerPixel, screen->format->Rmask, screen->format->Gmask, screen->format->Bmask, screen->format->Amask);
+
+ SDL_FillRect(temp, 0, color);
+ SDL_SetAlpha(temp, SDL_SRCALPHA | SDL_RLEACCEL, a);
+ SDL_BlitSurface(temp, 0, screen, &rect);
+ SDL_FreeSurface(temp);
+ }
+ }
+}
+
+void
+SDLRenderer::draw_filled_rect(const DrawingRequest& request)
+{
+ const FillRectRequest* fillrectrequest
+ = (FillRectRequest*) request.request_data;
+
+ SDL_Rect rect;
+ rect.x = (Sint16)request.pos.x * screen->w / SCREEN_WIDTH;
+ rect.y = (Sint16)request.pos.y * screen->h / SCREEN_HEIGHT;
+ rect.w = (Uint16)fillrectrequest->size.x * screen->w / SCREEN_WIDTH;
+ rect.h = (Uint16)fillrectrequest->size.y * screen->h / SCREEN_HEIGHT;
+ Uint8 r = static_cast<Uint8>(fillrectrequest->color.red * 255);
+ Uint8 g = static_cast<Uint8>(fillrectrequest->color.green * 255);
+ Uint8 b = static_cast<Uint8>(fillrectrequest->color.blue * 255);
+ Uint8 a = static_cast<Uint8>(fillrectrequest->color.alpha * 255);
+ Uint32 color = SDL_MapRGB(screen->format, r, g, b);
+ if(a == SDL_ALPHA_OPAQUE) {
+ SDL_FillRect(screen, &rect, color);
+ } else if(a != SDL_ALPHA_TRANSPARENT) {
+ SDL_Surface *temp = SDL_CreateRGBSurface(screen->flags, rect.w, rect.h, screen->format->BitsPerPixel, screen->format->Rmask, screen->format->Gmask, screen->format->Bmask, screen->format->Amask);
+
+ SDL_FillRect(temp, 0, color);
+ SDL_SetAlpha(temp, SDL_SRCALPHA | SDL_RLEACCEL, a);
+ SDL_BlitSurface(temp, 0, screen, &rect);
+ SDL_FreeSurface(temp);
+ }
+}
+
+void
+SDLRenderer::draw_inverse_ellipse(const DrawingRequest&)
+{
+}
+
+void
+SDLRenderer::do_take_screenshot()
+{
+ // [Christoph] TODO: Yes, this method also takes care of the actual disk I/O. Split it?
+
+ SDL_Surface *screen = SDL_GetVideoSurface();
+
+ // save screenshot
+ static const std::string writeDir = PHYSFS_getWriteDir();
+ static const std::string dirSep = PHYSFS_getDirSeparator();
+ static const std::string baseName = "screenshot";
+ static const std::string fileExt = ".bmp";
+ std::string fullFilename;
+ for (int num = 0; num < 1000; num++) {
+ std::ostringstream oss;
+ oss << baseName;
+ oss << std::setw(3) << std::setfill('0') << num;
+ oss << fileExt;
+ std::string fileName = oss.str();
+ fullFilename = writeDir + dirSep + fileName;
+ if (!PHYSFS_exists(fileName.c_str())) {
+ SDL_SaveBMP(screen, fullFilename.c_str());
+ log_debug << "Wrote screenshot to \"" << fullFilename << "\"" << std::endl;
+ return;
+ }
+ }
+ log_warning << "Did not save screenshot, because all files up to \"" << fullFilename << "\" already existed" << std::endl;
+}
+
+void
+SDLRenderer::flip()
+{
+ SDL_Flip(screen);
+}
+
+void
+SDLRenderer::resize(int, int)
+{
+
+}
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_VIDEO_SDL_RENDERER_HPP
+#define HEADER_SUPERTUX_VIDEO_SDL_RENDERER_HPP
+
+#include <SDL_video.h>
+
+#include "video/renderer.hpp"
+
+class SDLRenderer : public Renderer
+{
+public:
+ SDLRenderer();
+ ~SDLRenderer();
+
+ void draw_surface(const DrawingRequest& request);
+ void draw_surface_part(const DrawingRequest& request);
+ void draw_text(const DrawingRequest& request);
+ void draw_gradient(const DrawingRequest& request);
+ void draw_filled_rect(const DrawingRequest& request);
+ void draw_inverse_ellipse(const DrawingRequest& request);
+ void do_take_screenshot();
+ void flip();
+ void resize(int w, int h);
+ void apply_config() {}
+
+private:
+ SDL_Surface *screen;
+ int numerator, denominator;
+};
+
+#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_VIDEO_SDL_SURFACE_DATA_HPP
+#define HEADER_SUPERTUX_VIDEO_SDL_SURFACE_DATA_HPP
+
+#include <config.h>
+
+#include "supertux/gameconfig.hpp"
+#include "supertux/main.hpp"
+#include "video/surface.hpp"
+#include "video/texture.hpp"
+
+class SDLSurfaceData
+{
+private:
+ const Surface &surface;
+ SDL_Rect src_rects[NUM_EFFECTS];
+
+public:
+ SDLSurfaceData(const Surface &surface) :
+ surface(surface)
+ {
+ int numerator = 1;
+ int denominator = 1;
+ //float xfactor = 1.0f; // FIXME: (float) config->screenwidth / SCREEN_WIDTH;
+ //float yfactor = 1.0f; // FIXME: (float) config->screenheight / SCREEN_HEIGHT;
+
+ /* FIXME:
+ if(xfactor < yfactor)
+ {
+ numerator = config->screenwidth;
+ denominator = SCREEN_WIDTH;
+ }
+ else
+ {
+ numerator = config->screenheight;
+ denominator = SCREEN_HEIGHT;
+ }
+ */
+
+ src_rects[NO_EFFECT].x = surface.get_x() * numerator / denominator;
+ src_rects[NO_EFFECT].y = surface.get_y() * numerator / denominator;
+ src_rects[NO_EFFECT].w = surface.get_width() * numerator / denominator;
+ src_rects[NO_EFFECT].h = surface.get_height() * numerator / denominator;
+
+ int flipped_x = surface.get_texture()->get_texture_width() - surface.get_x() - surface.get_width();
+ src_rects[HORIZONTAL_FLIP].x = flipped_x * numerator / denominator;
+ src_rects[HORIZONTAL_FLIP].y = surface.get_y() * numerator / denominator;
+ src_rects[HORIZONTAL_FLIP].w = surface.get_width() * numerator / denominator;
+ src_rects[HORIZONTAL_FLIP].h = surface.get_height() * numerator / denominator;
+
+ int flipped_y = surface.get_texture()->get_texture_height() - surface.get_y() - surface.get_height();
+ src_rects[VERTICAL_FLIP].x = flipped_y * numerator / denominator;
+ src_rects[VERTICAL_FLIP].y = surface.get_y() * numerator / denominator;
+ src_rects[VERTICAL_FLIP].w = surface.get_width() * numerator / denominator;
+ src_rects[VERTICAL_FLIP].h = surface.get_height() * numerator / denominator;
+ }
+
+ SDL_Rect *get_src_rect(DrawingEffect effect)
+ {
+ return src_rects + effect;
+ }
+};
+
+#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include <config.h>
+
+#include "supertux/gameconfig.hpp"
+#include "supertux/main.hpp"
+#include "video/color.hpp"
+#include "video/sdl/sdl_texture.hpp"
+
+#include <assert.h>
+
+#include <SDL.h>
+
+namespace {
+#define BILINEAR
+
+#ifdef NAIVE
+SDL_Surface *scale(SDL_Surface *src, int numerator, int denominator)
+{
+ if(numerator == denominator)
+ {
+ src->refcount++;
+ return src;
+ }
+ else
+ {
+ SDL_Surface *dst = SDL_CreateRGBSurface(src->flags, src->w * numerator / denominator, src->h * numerator / denominator, src->format->BitsPerPixel, src->format->Rmask, src->format->Gmask, src->format->Bmask, src->format->Amask);
+ int bpp = dst->format->BytesPerPixel;
+ if(SDL_MUSTLOCK(src))
+ {
+ SDL_LockSurface(src);
+ }
+ if(SDL_MUSTLOCK(dst))
+ {
+ SDL_LockSurface(dst);
+ }
+ for(int y = 0;y < dst->h;y++) {
+ for(int x = 0;x < dst->w;x++) {
+ Uint8 *srcpixel = (Uint8 *) src->pixels + (y * denominator / numerator) * src->pitch + (x * denominator / numerator) * bpp;
+ Uint8 *dstpixel = (Uint8 *) dst->pixels + y * dst->pitch + x * bpp;
+ switch(bpp) {
+ case 4:
+ dstpixel[3] = srcpixel[3];
+ case 3:
+ dstpixel[2] = srcpixel[2];
+ case 2:
+ dstpixel[1] = srcpixel[1];
+ case 1:
+ dstpixel[0] = srcpixel[0];
+ }
+ }
+ }
+ if(SDL_MUSTLOCK(dst))
+ {
+ SDL_UnlockSurface(dst);
+ }
+ if(SDL_MUSTLOCK(src))
+ {
+ SDL_UnlockSurface(src);
+ }
+ if(!src->format->Amask)
+ {
+ if(src->flags & SDL_SRCALPHA)
+ {
+ SDL_SetAlpha(dst, SDL_SRCALPHA | SDL_RLEACCEL, src->format->alpha);
+ }
+ if(src->flags & SDL_SRCCOLORKEY)
+ {
+ SDL_SetColorKey(dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, src->format->colorkey);
+ }
+ }
+ return dst;
+ }
+} // namespace
+#endif
+
+#ifdef BILINEAR
+void getpixel(SDL_Surface *src, int srcx, int srcy, Uint8 color[4])
+{
+ int bpp = src->format->BytesPerPixel;
+ if(srcx == src->w)
+ {
+ srcx--;
+ }
+ if(srcy == src->h)
+ {
+ srcy--;
+ }
+ Uint8 *srcpixel = (Uint8 *) src->pixels + srcy * src->pitch + srcx * bpp;
+ Uint32 mapped = 0;
+ switch(bpp) {
+ case 1:
+ mapped = *srcpixel;
+ break;
+ case 2:
+ mapped = *(Uint16 *)srcpixel;
+ break;
+ case 3:
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ mapped |= srcpixel[0] << 16;
+ mapped |= srcpixel[1] << 8;
+ mapped |= srcpixel[2] << 0;
+#else
+ mapped |= srcpixel[0] << 0;
+ mapped |= srcpixel[1] << 8;
+ mapped |= srcpixel[2] << 16;
+#endif
+ break;
+ case 4:
+ mapped = *(Uint32 *)srcpixel;
+ break;
+ }
+ SDL_GetRGBA(mapped, src->format, &color[0], &color[1], &color[2], &color[3]);
+}
+
+void merge(Uint8 color[4], Uint8 color0[4], Uint8 color1[4], int rem, int total)
+{
+ color[0] = (color0[0] * (total - rem) + color1[0] * rem) / total;
+ color[1] = (color0[1] * (total - rem) + color1[1] * rem) / total;
+ color[2] = (color0[2] * (total - rem) + color1[2] * rem) / total;
+ color[3] = (color0[3] * (total - rem) + color1[3] * rem) / total;
+}
+
+SDL_Surface *scale(SDL_Surface *src, int numerator, int denominator)
+{
+ if(numerator == denominator)
+ {
+ src->refcount++;
+ return src;
+ }
+ else
+ {
+ SDL_Surface *dst = SDL_CreateRGBSurface(src->flags, src->w * numerator / denominator, src->h * numerator / denominator, src->format->BitsPerPixel, src->format->Rmask, src->format->Gmask, src->format->Bmask, src->format->Amask);
+ int bpp = dst->format->BytesPerPixel;
+ if(SDL_MUSTLOCK(src))
+ {
+ SDL_LockSurface(src);
+ }
+ if(SDL_MUSTLOCK(dst))
+ {
+ SDL_LockSurface(dst);
+ }
+ for(int y = 0;y < dst->h;y++) {
+ for(int x = 0;x < dst->w;x++) {
+ int srcx = x * denominator / numerator;
+ int srcy = y * denominator / numerator;
+ Uint8 color00[4], color01[4], color10[4], color11[4];
+ getpixel(src, srcx, srcy, color00);
+ getpixel(src, srcx + 1, srcy, color01);
+ getpixel(src, srcx, srcy + 1, color10);
+ getpixel(src, srcx + 1, srcy + 1, color11);
+ Uint8 color0[4], color1[4], color[4];
+ int remx = x * denominator % numerator;
+ merge(color0, color00, color01, remx, numerator);
+ merge(color1, color10, color11, remx, numerator);
+ int remy = y * denominator % numerator;
+ merge(color, color0, color1, remy, numerator);
+ Uint8 *dstpixel = (Uint8 *) dst->pixels + y * dst->pitch + x * bpp;
+ Uint32 mapped = SDL_MapRGBA(dst->format, color[0], color[1], color[2], color[3]);
+ switch(bpp) {
+ case 1:
+ *dstpixel = mapped;
+ break;
+ case 2:
+ *(Uint16 *)dstpixel = mapped;
+ break;
+ case 3:
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ dstpixel[0] = (mapped >> 16) & 0xff;
+ dstpixel[1] = (mapped >> 8) & 0xff;
+ dstpixel[2] = (mapped >> 0) & 0xff;
+#else
+ dstpixel[0] = (mapped >> 0) & 0xff;
+ dstpixel[1] = (mapped >> 8) & 0xff;
+ dstpixel[2] = (mapped >> 16) & 0xff;
+#endif
+ break;
+ case 4:
+ *(Uint32 *)dstpixel = mapped;
+ break;
+ }
+ }
+ }
+ if(SDL_MUSTLOCK(dst))
+ {
+ SDL_UnlockSurface(dst);
+ }
+ if(SDL_MUSTLOCK(src))
+ {
+ SDL_UnlockSurface(src);
+ }
+ if(!src->format->Amask)
+ {
+ if(src->flags & SDL_SRCALPHA)
+ {
+ SDL_SetAlpha(dst, SDL_SRCALPHA | SDL_RLEACCEL, src->format->alpha);
+ }
+ if(src->flags & SDL_SRCCOLORKEY)
+ {
+ SDL_SetColorKey(dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, src->format->colorkey);
+ }
+ }
+ return dst;
+ }
+}
+#endif
+
+SDL_Surface *horz_flip(SDL_Surface *src)
+{
+ SDL_Surface *dst = SDL_CreateRGBSurface(src->flags, src->w, src->h, src->format->BitsPerPixel, src->format->Rmask, src->format->Gmask, src->format->Bmask, src->format->Amask);
+ int bpp = dst->format->BytesPerPixel;
+ if(SDL_MUSTLOCK(src))
+ {
+ SDL_LockSurface(src);
+ }
+ if(SDL_MUSTLOCK(dst))
+ {
+ SDL_LockSurface(dst);
+ }
+ for(int y = 0;y < dst->h;y++) {
+ for(int x = 0;x < dst->w;x++) {
+ Uint8 *srcpixel = (Uint8 *) src->pixels + y * src->pitch + x * bpp;
+ Uint8 *dstpixel = (Uint8 *) dst->pixels + y * dst->pitch + (dst->w - x - 1) * bpp;
+ switch(bpp) {
+ case 4:
+ dstpixel[3] = srcpixel[3];
+ case 3:
+ dstpixel[2] = srcpixel[2];
+ case 2:
+ dstpixel[1] = srcpixel[1];
+ case 1:
+ dstpixel[0] = srcpixel[0];
+ }
+ }
+ }
+ if(SDL_MUSTLOCK(dst))
+ {
+ SDL_UnlockSurface(dst);
+ }
+ if(SDL_MUSTLOCK(src))
+ {
+ SDL_UnlockSurface(src);
+ }
+ if(!src->format->Amask)
+ {
+ if(src->flags & SDL_SRCALPHA)
+ {
+ SDL_SetAlpha(dst, SDL_SRCALPHA | SDL_RLEACCEL, src->format->alpha);
+ }
+ if(src->flags & SDL_SRCCOLORKEY)
+ {
+ SDL_SetColorKey(dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, src->format->colorkey);
+ }
+ }
+ return dst;
+}
+
+SDL_Surface *vert_flip(SDL_Surface *src)
+{
+ SDL_Surface *dst = SDL_CreateRGBSurface(src->flags, src->w, src->h, src->format->BitsPerPixel, src->format->Rmask, src->format->Gmask, src->format->Bmask, src->format->Amask);
+ int bpp = dst->format->BytesPerPixel;
+ if(SDL_MUSTLOCK(src))
+ {
+ SDL_LockSurface(src);
+ }
+ if(SDL_MUSTLOCK(dst))
+ {
+ SDL_LockSurface(dst);
+ }
+ for(int y = 0;y < dst->h;y++) {
+ for(int x = 0;x < dst->w;x++) {
+ Uint8 *srcpixel = (Uint8 *) src->pixels + y * src->pitch + x * bpp;
+ Uint8 *dstpixel = (Uint8 *) dst->pixels + (dst->h - y - 1) * dst->pitch + x * bpp;
+ switch(bpp) {
+ case 4:
+ dstpixel[3] = srcpixel[3];
+ case 3:
+ dstpixel[2] = srcpixel[2];
+ case 2:
+ dstpixel[1] = srcpixel[1];
+ case 1:
+ dstpixel[0] = srcpixel[0];
+ }
+ }
+ }
+ if(SDL_MUSTLOCK(dst))
+ {
+ SDL_UnlockSurface(dst);
+ }
+ if(SDL_MUSTLOCK(src))
+ {
+ SDL_UnlockSurface(src);
+ }
+ if(!src->format->Amask)
+ {
+ if(src->flags & SDL_SRCALPHA)
+ {
+ SDL_SetAlpha(dst, SDL_SRCALPHA | SDL_RLEACCEL, src->format->alpha);
+ }
+ if(src->flags & SDL_SRCCOLORKEY)
+ {
+ SDL_SetColorKey(dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, src->format->colorkey);
+ }
+ }
+ return dst;
+}
+
+SDL_Surface *colorize(SDL_Surface *src, const Color &color)
+{
+ // FIXME: This is really slow
+ assert(color.red != 1.0 || color.green != 1.0 || color.blue != 1.0);
+ int red = (int) (color.red * 256);
+ int green = (int) (color.green * 256);
+ int blue = (int) (color.blue * 256);
+ SDL_Surface *dst = SDL_CreateRGBSurface(src->flags, src->w, src->h, src->format->BitsPerPixel, src->format->Rmask, src->format->Gmask, src->format->Bmask, src->format->Amask);
+ int bpp = dst->format->BytesPerPixel;
+ if(SDL_MUSTLOCK(src))
+ {
+ SDL_LockSurface(src);
+ }
+ if(SDL_MUSTLOCK(dst))
+ {
+ SDL_LockSurface(dst);
+ }
+ for(int y = 0;y < dst->h;y++) {
+ for(int x = 0;x < dst->w;x++) {
+ Uint8 *srcpixel = (Uint8 *) src->pixels + y * src->pitch + x * bpp;
+ Uint8 *dstpixel = (Uint8 *) dst->pixels + y * dst->pitch + x * bpp;
+ Uint32 mapped = 0;
+ switch(bpp) {
+ case 1:
+ mapped = *srcpixel;
+ break;
+ case 2:
+ mapped = *(Uint16 *)srcpixel;
+ break;
+ case 3:
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ mapped |= srcpixel[0] << 16;
+ mapped |= srcpixel[1] << 8;
+ mapped |= srcpixel[2] << 0;
+#else
+ mapped |= srcpixel[0] << 0;
+ mapped |= srcpixel[1] << 8;
+ mapped |= srcpixel[2] << 16;
+#endif
+ break;
+ case 4:
+ mapped = *(Uint32 *)srcpixel;
+ break;
+ }
+ if(src->format->Amask || !(src->flags & SDL_SRCCOLORKEY) || mapped != src->format->colorkey)
+ {
+ Uint8 r, g, b, a;
+ SDL_GetRGBA(mapped, src->format, &r, &g, &b, &a);
+ mapped = SDL_MapRGBA(dst->format, (r * red) >> 8, (g * green) >> 8, (b * blue) >> 8, a);
+ }
+ switch(bpp) {
+ case 1:
+ *dstpixel = mapped;
+ break;
+ case 2:
+ *(Uint16 *)dstpixel = mapped;
+ break;
+ case 3:
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ dstpixel[0] = (mapped >> 16) & 0xff;
+ dstpixel[1] = (mapped >> 8) & 0xff;
+ dstpixel[2] = (mapped >> 0) & 0xff;
+#else
+ dstpixel[0] = (mapped >> 0) & 0xff;
+ dstpixel[1] = (mapped >> 8) & 0xff;
+ dstpixel[2] = (mapped >> 16) & 0xff;
+#endif
+ break;
+ case 4:
+ *(Uint32 *)dstpixel = mapped;
+ break;
+ }
+ }
+ }
+ if(SDL_MUSTLOCK(dst))
+ {
+ SDL_UnlockSurface(dst);
+ }
+ if(SDL_MUSTLOCK(src))
+ {
+ SDL_UnlockSurface(src);
+ }
+ if(!src->format->Amask)
+ {
+ if(src->flags & SDL_SRCALPHA)
+ {
+ SDL_SetAlpha(dst, SDL_SRCALPHA | SDL_RLEACCEL, src->format->alpha);
+ }
+ if(src->flags & SDL_SRCCOLORKEY)
+ {
+ SDL_SetColorKey(dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, src->format->colorkey);
+ }
+ }
+ return dst;
+}
+
+SDL_Surface *optimize(SDL_Surface *src)
+{
+ if(!src->format->Amask)
+ {
+ return SDL_DisplayFormat(src);
+ }
+ else
+ {
+ int transparent = 0;
+ int opaque = 0;
+ int semitransparent = 0;
+ int alphasum = 0;
+ int squaredalphasum = 0;
+ bool colors[(1 << 12)];
+ memset(colors, 0, (1 << 12) * sizeof(bool));
+
+ int bpp = src->format->BytesPerPixel;
+ if(SDL_MUSTLOCK(src))
+ {
+ SDL_LockSurface(src);
+ }
+ for(int y = 0;y < src->h;y++) {
+ for(int x = 0;x < src->w;x++) {
+ Uint8 *pixel = (Uint8 *) src->pixels + y * src->pitch + x * bpp;
+ Uint32 mapped = 0;
+ switch(bpp) {
+ case 1:
+ mapped = *pixel;
+ break;
+ case 2:
+ mapped = *(Uint16 *)pixel;
+ break;
+ case 3:
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ mapped |= pixel[0] << 16;
+ mapped |= pixel[1] << 8;
+ mapped |= pixel[2] << 0;
+#else
+ mapped |= pixel[0] << 0;
+ mapped |= pixel[1] << 8;
+ mapped |= pixel[2] << 16;
+#endif
+ break;
+ case 4:
+ mapped = *(Uint32 *)pixel;
+ break;
+ }
+ Uint8 red, green, blue, alpha;
+ SDL_GetRGBA(mapped, src->format, &red, &green, &blue, &alpha);
+ if(alpha < 16)
+ {
+ transparent++;
+ }
+ else if (alpha > 240)
+ {
+ opaque++;
+ alphasum += alpha;
+ squaredalphasum += alpha * alpha;
+ }
+ else
+ {
+ semitransparent++;
+ squaredalphasum += alpha * alpha;
+ }
+ if(alpha != 0)
+ {
+ colors[((red & 0xf0) << 4) | (green & 0xf0) | ((blue & 0xf0) >> 4)] = true;
+ }
+ }
+ }
+ if(SDL_MUSTLOCK(src))
+ {
+ SDL_UnlockSurface(src);
+ }
+ int avgalpha = (opaque + semitransparent) ? alphasum / (opaque + semitransparent) : 0;
+ int avgsquaredalpha = (opaque + semitransparent) ? squaredalphasum / (opaque + semitransparent) : 0;
+ int alphavariance = avgsquaredalpha - avgalpha * avgalpha;
+ if(semitransparent > ((transparent + opaque + semitransparent) / 8) && alphavariance > 16)
+ {
+ return SDL_DisplayFormatAlpha(src);
+ }
+ int keycolor = -1;
+ for(int i = 0;i < (1 << 12);i++)
+ {
+ if(!colors[i])
+ {
+ keycolor = i;
+ }
+ }
+ if(keycolor == -1)
+ {
+ return SDL_DisplayFormatAlpha(src);
+ }
+ SDL_Surface *dst = SDL_CreateRGBSurface(src->flags & ~(SDL_SRCALPHA), src->w, src->h, src->format->BitsPerPixel, src->format->Rmask, src->format->Gmask, src->format->Bmask, 0);
+ bpp = dst->format->BytesPerPixel;
+ Uint32 key = SDL_MapRGB(dst->format, (((keycolor & 0xf00) >> 4) | 0xf), ((keycolor & 0xf0) | 0xf), (((keycolor & 0xf) << 4) | 0xf));
+ if(SDL_MUSTLOCK(src))
+ {
+ SDL_LockSurface(src);
+ }
+ if(SDL_MUSTLOCK(dst))
+ {
+ SDL_LockSurface(dst);
+ }
+ for(int y = 0;y < dst->h;y++) {
+ for(int x = 0;x < dst->w;x++) {
+ Uint8 *srcpixel = (Uint8 *) src->pixels + y * src->pitch + x * bpp;
+ Uint8 *dstpixel = (Uint8 *) dst->pixels + y * dst->pitch + x * bpp;
+ Uint32 mapped = 0;
+ switch(bpp) {
+ case 1:
+ mapped = *srcpixel;
+ break;
+ case 2:
+ mapped = *(Uint16 *)srcpixel;
+ break;
+ case 3:
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ mapped |= srcpixel[0] << 16;
+ mapped |= srcpixel[1] << 8;
+ mapped |= srcpixel[2] << 0;
+#else
+ mapped |= srcpixel[0] << 0;
+ mapped |= srcpixel[1] << 8;
+ mapped |= srcpixel[2] << 16;
+#endif
+ break;
+ case 4:
+ mapped = *(Uint32 *)srcpixel;
+ break;
+ }
+ Uint8 red, green, blue, alpha;
+ SDL_GetRGBA(mapped, src->format, &red, &green, &blue, &alpha);
+ if(alpha < (avgalpha / 4))
+ {
+ mapped = key;
+ }
+ else
+ {
+ mapped = SDL_MapRGB(dst->format, red, green, blue);
+ }
+ switch(bpp) {
+ case 1:
+ *dstpixel = mapped;
+ break;
+ case 2:
+ *(Uint16 *)dstpixel = mapped;
+ break;
+ case 3:
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ dstpixel[0] = (mapped >> 16) & 0xff;
+ dstpixel[1] = (mapped >> 8) & 0xff;
+ dstpixel[2] = (mapped >> 0) & 0xff;
+#else
+ dstpixel[0] = (mapped >> 0) & 0xff;
+ dstpixel[1] = (mapped >> 8) & 0xff;
+ dstpixel[2] = (mapped >> 16) & 0xff;
+#endif
+ break;
+ case 4:
+ *(Uint32 *)dstpixel = mapped;
+ break;
+ }
+ }
+ }
+ if(SDL_MUSTLOCK(dst))
+ {
+ SDL_UnlockSurface(dst);
+ }
+ if(SDL_MUSTLOCK(src))
+ {
+ SDL_UnlockSurface(src);
+ }
+ if(avgalpha < 240)
+ {
+ SDL_SetAlpha(dst, SDL_SRCALPHA | SDL_RLEACCEL, avgalpha);
+ }
+ SDL_SetColorKey(dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, key);
+ SDL_Surface *convert = SDL_DisplayFormat(dst);
+ SDL_FreeSurface(dst);
+ return convert;
+ }
+}
+}
+
+SDLTexture::SDLTexture(SDL_Surface* image)
+{
+ texture = optimize(image);
+ //width = texture->w;
+ //height = texture->h;
+ int numerator = 1;
+ int denominator = 1;
+ //FIXME: float xfactor = (float) config->screenwidth / SCREEN_WIDTH;
+ //FIXME: float yfactor = (float) config->screenheight / SCREEN_HEIGHT;
+ /* FIXME:
+ if(xfactor < yfactor)
+ {
+ numerator = config->screenwidth;
+ denominator = SCREEN_WIDTH;
+ }
+ else
+ {
+ numerator = config->screenheight;
+ denominator = SCREEN_HEIGHT;
+ }
+ */
+ cache[NO_EFFECT][Color::WHITE] = scale(texture, numerator, denominator);
+}
+
+SDLTexture::~SDLTexture()
+{
+ SDL_FreeSurface(texture);
+}
+
+SDL_Surface*
+SDLTexture::get_transform(const Color &color, DrawingEffect effect)
+{
+ if(cache[NO_EFFECT][color] == 0) {
+ assert(cache[NO_EFFECT][Color::WHITE]);
+ cache[NO_EFFECT][color] = colorize(cache[NO_EFFECT][Color::WHITE], color);
+ }
+ if(cache[effect][color] == 0) {
+ assert(cache[NO_EFFECT][color]);
+ switch(effect) {
+ case NO_EFFECT:
+ break;
+ case HORIZONTAL_FLIP:
+ cache[HORIZONTAL_FLIP][color] = horz_flip(cache[NO_EFFECT][color]);
+ break;
+ case VERTICAL_FLIP:
+ cache[VERTICAL_FLIP][color] = vert_flip(cache[NO_EFFECT][color]);
+ break;
+ default:
+ return 0;
+ }
+ }
+ return cache[effect][color];
+}
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_VIDEO_SDL_TEXTURE_HPP
+#define HEADER_SUPERTUX_VIDEO_SDL_TEXTURE_HPP
+
+#include <algorithm>
+#include <config.h>
+
+#include <SDL.h>
+
+#include "video/color.hpp"
+#include "video/texture.hpp"
+
+class SDLTexture : public Texture
+{
+protected:
+ SDL_Surface *texture;
+ //unsigned int width;
+ //unsigned int height;
+
+ struct ColorCache
+ {
+ static const int HASHED_BITS = 3;
+ static const int CACHE_SIZE = 1 << (HASHED_BITS * 3);
+
+ static void ref(SDL_Surface *surface)
+ {
+ if(surface)
+ {
+ surface->refcount++;
+ }
+ }
+
+ static int hash(const Color &color)
+ {
+ return
+ ((int) (color.red * ((1 << HASHED_BITS) - 1)) << (HASHED_BITS - 1) * 2) |
+ ((int) (color.green * ((1 << HASHED_BITS) - 1)) << (HASHED_BITS - 1)) |
+ ((int) (color.blue * ((1 << HASHED_BITS) - 1)) << 0);
+ }
+
+ SDL_Surface *data[CACHE_SIZE];
+
+ ColorCache()
+ {
+ memset(data, 0, CACHE_SIZE * sizeof(SDL_Surface *));
+ }
+
+ ~ColorCache()
+ {
+ std::for_each(data, data + CACHE_SIZE, SDL_FreeSurface);
+ }
+
+ void operator = (const ColorCache &other)
+ {
+ std::for_each(other.data, other.data + CACHE_SIZE, ref);
+ std::for_each(data, data + CACHE_SIZE, SDL_FreeSurface);
+ memcpy(data, other.data, CACHE_SIZE * sizeof(SDL_Surface *));
+ }
+
+ SDL_Surface *&operator [] (const Color &color)
+ {
+ return data[hash(color)];
+ }
+ };
+ //typedef std::map<Color, SDL_Surface *> ColorCache;
+ ColorCache cache[NUM_EFFECTS];
+
+public:
+ SDLTexture(SDL_Surface* sdlsurface);
+ virtual ~SDLTexture();
+
+ SDL_Surface *get_transform(const Color &color, DrawingEffect effect);
+
+ SDL_Surface *get_texture() const
+ {
+ return texture;
+ }
+
+ unsigned int get_texture_width() const
+ {
+ return texture->w;
+ }
+
+ unsigned int get_texture_height() const
+ {
+ return texture->h;
+ }
+
+ unsigned int get_image_width() const
+ {
+ return texture->w;
+ }
+
+ unsigned int get_image_height() const
+ {
+ return texture->h;
+ }
+
+ /*unsigned int get_texture_width() const
+ {
+ return width;
+ }
+
+ unsigned int get_texture_height() const
+ {
+ return height;
+ }
+
+ unsigned int get_image_width() const
+ {
+ return width;
+ }
+
+ unsigned int get_image_height() const
+ {
+ return height;
+ }*/
+};
+
+#endif
+
+/* EOF */
+++ /dev/null
-// $Id: sdl_lightmap.cpp 5063 2007-05-27 11:32:00Z matzeb $
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include <config.h>
-
-#include <functional>
-#include <algorithm>
-#include <cassert>
-#include <iostream>
-#include <SDL_image.h>
-#include <sstream>
-#include <iomanip>
-#include <physfs.h>
-
-#include "glutil.hpp"
-#include "sdl_lightmap.hpp"
-#include "sdl_texture.hpp"
-#include "sdl_surface_data.hpp"
-#include "drawing_context.hpp"
-#include "drawing_request.hpp"
-#include "renderer.hpp"
-#include "surface.hpp"
-#include "font.hpp"
-#include "main.hpp"
-#include "gameconfig.hpp"
-#include "texture.hpp"
-#include "texture_manager.hpp"
-#include "obstack/obstackpp.hpp"
-
-namespace SDL
-{
- Lightmap::Lightmap()
- {
- screen = SDL_GetVideoSurface();
-
- //float xfactor = 1.0f; // FIXME: (float) config->screenwidth / SCREEN_WIDTH;
- //float yfactor = 1.0f; // FIXME: (float) config->screenheight / SCREEN_HEIGHT;
-
- numerator = 1;
- denominator = 1;
-
- /* FIXME:
- if(xfactor < yfactor)
- {
- numerator = config->screenwidth;
- denominator = SCREEN_WIDTH;
- }
- else
- {
- numerator = config->screenheight;
- denominator = SCREEN_HEIGHT;
- }
- */
-
- LIGHTMAP_DIV = 8 * numerator / denominator;
-
- width = screen->w / LIGHTMAP_DIV;
- height = screen->h / LIGHTMAP_DIV;
-
- red_channel = (Uint8 *)malloc(width * height * sizeof(Uint8));
- green_channel = (Uint8 *)malloc(width * height * sizeof(Uint8));
- blue_channel = (Uint8 *)malloc(width * height * sizeof(Uint8));
- }
-
- Lightmap::~Lightmap()
- {
- free(red_channel);
- free(green_channel);
- free(blue_channel);
- }
-
- void
- Lightmap::start_draw(const Color &ambient_color)
- {
- memset(red_channel, (Uint8) (ambient_color.red * 255), width * height * sizeof(Uint8));
- memset(green_channel, (Uint8) (ambient_color.green * 255), width * height * sizeof(Uint8));
- memset(blue_channel, (Uint8) (ambient_color.blue * 255), width * height * sizeof(Uint8));
- }
-
- void
- Lightmap::end_draw()
- {
- }
-
-//#define BILINEAR
-
-#ifdef BILINEAR
- namespace
- {
- void merge(Uint8 color[3], Uint8 color0[3], Uint8 color1[3], int rem, int total)
- {
- color[0] = (color0[0] * (total - rem) + color1[0] * rem) / total;
- color[1] = (color0[1] * (total - rem) + color1[1] * rem) / total;
- color[2] = (color0[2] * (total - rem) + color1[2] * rem) / total;
- }
- }
-#endif
-
- void
- Lightmap::do_draw()
- {
- // FIXME: This is really slow
- if(LIGHTMAP_DIV == 1)
- {
- int bpp = screen->format->BytesPerPixel;
- if(SDL_MUSTLOCK(screen))
- {
- SDL_LockSurface(screen);
- }
- Uint8 *pixel = (Uint8 *) screen->pixels;
- int loc = 0;
- for(int y = 0;y < height;y++) {
- for(int x = 0;x < width;x++, pixel += bpp, loc++) {
- if(red_channel[loc] == 0xff && green_channel[loc] == 0xff && blue_channel[loc] == 0xff)
- {
- continue;
- }
- Uint32 mapped = 0;
- switch(bpp) {
- case 1:
- mapped = *pixel;
- break;
- case 2:
- mapped = *(Uint16 *)pixel;
- break;
- case 3:
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- mapped |= pixel[0] << 16;
- mapped |= pixel[1] << 8;
- mapped |= pixel[2] << 0;
-#else
- mapped |= pixel[0] << 0;
- mapped |= pixel[1] << 8;
- mapped |= pixel[2] << 16;
-#endif
- break;
- case 4:
- mapped = *(Uint32 *)pixel;
- break;
- }
- Uint8 red, green, blue, alpha;
- SDL_GetRGBA(mapped, screen->format, &red, &green, &blue, &alpha);
- red = (red * red_channel[loc]) >> 8;
- green = (green * green_channel[loc]) >> 8;
- blue = (blue * blue_channel[loc]) >> 8;
- mapped = SDL_MapRGBA(screen->format, red, green, blue, alpha);
- switch(bpp) {
- case 1:
- *pixel = mapped;
- break;
- case 2:
- *(Uint16 *)pixel = mapped;
- break;
- case 3:
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- pixel[0] = (mapped >> 16) & 0xff;
- pixel[1] = (mapped >> 8) & 0xff;
- pixel[2] = (mapped >> 0) & 0xff;
-#else
- pixel[0] = (mapped >> 0) & 0xff;
- pixel[1] = (mapped >> 8) & 0xff;
- pixel[2] = (mapped >> 16) & 0xff;
-#endif
- break;
- case 4:
- *(Uint32 *)pixel = mapped;
- break;
- }
- }
- pixel += screen->pitch - width * bpp;
- }
- if(SDL_MUSTLOCK(screen))
- {
- SDL_UnlockSurface(screen);
- }
- }
- else
- {
- int bpp = screen->format->BytesPerPixel;
- if(SDL_MUSTLOCK(screen))
- {
- SDL_LockSurface(screen);
- }
- Uint8 *div_pixel = (Uint8 *) screen->pixels;
- int loc = 0;
- for(int y = 0;y < height;y++) {
- for(int x = 0;x < width;x++, div_pixel += bpp * LIGHTMAP_DIV, loc++) {
- if(red_channel[loc] == 0xff && green_channel[loc] == 0xff && blue_channel[loc] == 0xff)
- {
- continue;
- }
- Uint8 *pixel = div_pixel;
- for(int div_y = 0;div_y < LIGHTMAP_DIV;div_y++) {
- for(int div_x = 0;div_x < LIGHTMAP_DIV;pixel += bpp, div_x++) {
- Uint32 mapped = 0;
- switch(bpp) {
- case 1:
- mapped = *pixel;
- break;
- case 2:
- mapped = *(Uint16 *)pixel;
- break;
- case 3:
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- mapped |= pixel[0] << 16;
- mapped |= pixel[1] << 8;
- mapped |= pixel[2] << 0;
-#else
- mapped |= pixel[0] << 0;
- mapped |= pixel[1] << 8;
- mapped |= pixel[2] << 16;
-#endif
- break;
- case 4:
- mapped = *(Uint32 *)pixel;
- break;
- }
- Uint8 red, green, blue, alpha;
- SDL_GetRGBA(mapped, screen->format, &red, &green, &blue, &alpha);
-
-#ifdef BILINEAR
- int xinc = (x + 1 != width ? 1 : 0);
- int yinc = (y + 1 != height ? width : 0);
- Uint8 color00[3], color01[3], color10[3], color11[3];
- {
- color00[0] = red_channel[loc];
- color00[1] = green_channel[loc];
- color00[2] = blue_channel[loc];
- }
- {
- color01[0] = red_channel[loc + xinc];
- color01[1] = green_channel[loc + xinc];
- color01[2] = blue_channel[loc + xinc];
- }
- {
- color10[0] = red_channel[loc + yinc];
- color10[1] = green_channel[loc + yinc];
- color10[2] = blue_channel[loc + yinc];
- }
- {
- color11[0] = red_channel[loc + yinc + xinc];
- color11[1] = green_channel[loc + yinc + xinc];
- color11[2] = blue_channel[loc + yinc + xinc];
- }
- Uint8 color0[3], color1[3], color[3];
- merge(color0, color00, color01, div_x, LIGHTMAP_DIV);
- merge(color1, color10, color11, div_x, LIGHTMAP_DIV);
- merge(color, color0, color1, div_y, LIGHTMAP_DIV);
- red = (red * color[0]) >> 8;
- green = (green * color[1]) >> 8;
- blue = (blue * color[2]) >> 8;
-#else
- red = (red * red_channel[loc]) >> 8;
- green = (green * green_channel[loc]) >> 8;
- blue = (blue * blue_channel[loc]) >> 8;
-#endif
-
- mapped = SDL_MapRGBA(screen->format, red, green, blue, alpha);
- switch(bpp) {
- case 1:
- *pixel = mapped;
- break;
- case 2:
- *(Uint16 *)pixel = mapped;
- break;
- case 3:
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- pixel[0] = (mapped >> 16) & 0xff;
- pixel[1] = (mapped >> 8) & 0xff;
- pixel[2] = (mapped >> 0) & 0xff;
-#else
- pixel[0] = (mapped >> 0) & 0xff;
- pixel[1] = (mapped >> 8) & 0xff;
- pixel[2] = (mapped >> 16) & 0xff;
-#endif
- break;
- case 4:
- *(Uint32 *)pixel = mapped;
- break;
- }
- }
- pixel += screen->pitch - LIGHTMAP_DIV * bpp;
- }
- }
- div_pixel += (screen->pitch - width * bpp) * LIGHTMAP_DIV;
- }
- if(SDL_MUSTLOCK(screen))
- {
- SDL_UnlockSurface(screen);
- }
- }
- }
-
- void Lightmap::light_blit(SDL_Surface *src, SDL_Rect *src_rect, int dstx, int dsty)
- {
- dstx /= LIGHTMAP_DIV;
- dsty /= LIGHTMAP_DIV;
- int srcx = src_rect->x / LIGHTMAP_DIV;
- int srcy = src_rect->y / LIGHTMAP_DIV;
- int blit_width = src_rect->w / LIGHTMAP_DIV;
- int blit_height = src_rect->h / LIGHTMAP_DIV;
- int bpp = src->format->BytesPerPixel;
- if(SDL_MUSTLOCK(src))
- {
- SDL_LockSurface(src);
- }
- Uint8 *pixel = (Uint8 *) src->pixels + srcy * src->pitch + srcx * bpp;
- int loc = dsty * width + dstx;
- for(int y = 0;y < blit_height;y++) {
- for(int x = 0;x < blit_width;x++, pixel += bpp * LIGHTMAP_DIV, loc++) {
- if(x + dstx < 0 || y + dsty < 0 || x + dstx >= width || y + dsty >= height)
- {
- continue;
- }
- if(red_channel[loc] == 0xff && green_channel[loc] == 0xff && blue_channel[loc] == 0xff)
- {
- continue;
- }
-
- Uint32 mapped = 0;
- switch(bpp) {
- case 1:
- mapped = *pixel;
- break;
- case 2:
- mapped = *(Uint16 *)pixel;
- break;
- case 3:
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- mapped |= pixel[0] << 16;
- mapped |= pixel[1] << 8;
- mapped |= pixel[2] << 0;
-#else
- mapped |= pixel[0] << 0;
- mapped |= pixel[1] << 8;
- mapped |= pixel[2] << 16;
-#endif
- break;
- case 4:
- mapped = *(Uint32 *)pixel;
- break;
- }
- Uint8 red, green, blue, alpha;
- SDL_GetRGBA(mapped, src->format, &red, &green, &blue, &alpha);
-
- if(red != 0)
- {
- int redsum = red_channel[loc] + (red * alpha >> 8);
- red_channel[loc] = redsum & ~0xff ? 0xff : redsum;
- }
- if(green != 0)
- {
- int greensum = green_channel[loc] + (green * alpha >> 8);
- green_channel[loc] = greensum & ~0xff ? 0xff : greensum;
- }
- if(blue != 0)
- {
- int bluesum = blue_channel[loc] + (blue * alpha >> 8);
- blue_channel[loc] = bluesum & ~0xff ? 0xff : bluesum;
- }
- }
- pixel += (src->pitch - blit_width * bpp) * LIGHTMAP_DIV;
- loc += width - blit_width;
- }
- if(SDL_MUSTLOCK(src))
- {
- SDL_UnlockSurface(src);
- }
- }
-
- /*void Lightmap::light_blit(SDL_Surface *src, SDL_Rect *src_rect, int dstx, int dsty)
- {
- int bpp = src->format->BytesPerPixel;
- if(SDL_MUSTLOCK(src))
- {
- SDL_LockSurface(src);
- }
- Uint8 *pixel = (Uint8 *) src->pixels + src_rect->y * src->pitch + src_rect->x * bpp;
- int loc = dsty * width + dstx;
- for(int y = 0;y < src_rect->h;y++) {
- for(int x = 0;x < src_rect->w;x++, pixel += bpp, loc++) {
- if(x + dstx < 0 || y + dsty < 0 || x + dstx >= width || y + dsty >= height)
- {
- continue;
- }
- if(red_channel[loc] == 0xff && green_channel[loc] == 0xff && blue_channel[loc] == 0xff)
- {
- continue;
- }
-
- Uint32 mapped = 0;
- switch(bpp) {
- case 1:
- mapped = *pixel;
- break;
- case 2:
- mapped = *(Uint16 *)pixel;
- break;
- case 3:
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- mapped |= pixel[0] << 16;
- mapped |= pixel[1] << 8;
- mapped |= pixel[2] << 0;
-#else
- mapped |= pixel[0] << 0;
- mapped |= pixel[1] << 8;
- mapped |= pixel[2] << 16;
-#endif
- break;
- case 4:
- mapped = *(Uint32 *)pixel;
- break;
- }
- Uint8 red, green, blue, alpha;
- SDL_GetRGBA(mapped, src->format, &red, &green, &blue, &alpha);
-
- if(red != 0)
- {
- int redsum = red_channel[loc] + (red * alpha >> 8);
- red_channel[loc] = redsum & ~0xff ? 0xff : redsum;
- }
- if(green != 0)
- {
- int greensum = green_channel[loc] + (green * alpha >> 8);
- green_channel[loc] = greensum & ~0xff ? 0xff : greensum;
- }
- if(blue != 0)
- {
- int bluesum = blue_channel[loc] + (blue * alpha >> 8);
- blue_channel[loc] = bluesum & ~0xff ? 0xff : bluesum;
- }
- }
- pixel += src->pitch - src_rect->w * bpp;
- loc += width - src_rect->w;
- }
- if(SDL_MUSTLOCK(src))
- {
- SDL_UnlockSurface(src);
- }
- }*/
-
- void
- Lightmap::draw_surface(const DrawingRequest& request)
- {
- if((request.color.red == 0.0 && request.color.green == 0.0 && request.color.blue == 0.0) || request.color.alpha == 0.0 || request.alpha == 0.0)
- {
- return;
- }
- //FIXME: support parameters request.alpha, request.angle, request.blend
-
- const Surface* surface = (const Surface*) request.request_data;
- SDL::Texture *sdltexture = dynamic_cast<SDL::Texture *>(surface->get_texture());
- SDL::SurfaceData *surface_data = reinterpret_cast<SDL::SurfaceData *>(surface->get_surface_data());
-
- DrawingEffect effect = request.drawing_effect;
- if (surface->get_flipx()) effect = HORIZONTAL_FLIP;
-
- SDL_Surface *transform = sdltexture->get_transform(request.color, effect);
-
- // get and check SDL_Surface
- if (transform == 0) {
- std::cerr << "Warning: Tried to draw NULL surface, skipped draw" << std::endl;
- return;
- }
-
- SDL_Rect *src_rect = surface_data->get_src_rect(effect);
- int dstx = (int) request.pos.x * numerator / denominator;
- int dsty = (int) request.pos.y * numerator / denominator;
- light_blit(transform, src_rect, dstx, dsty);
- }
-
- void
- Lightmap::draw_surface_part(const DrawingRequest& request)
- {
- const SurfacePartRequest* surfacepartrequest
- = (SurfacePartRequest*) request.request_data;
-
- const Surface* surface = surfacepartrequest->surface;
- SDL::Texture *sdltexture = dynamic_cast<SDL::Texture *>(surface->get_texture());
-
- DrawingEffect effect = request.drawing_effect;
- if (surface->get_flipx()) effect = HORIZONTAL_FLIP;
-
- SDL_Surface *transform = sdltexture->get_transform(Color(1.0, 1.0, 1.0), effect);
-
- // get and check SDL_Surface
- if (transform == 0) {
- std::cerr << "Warning: Tried to draw NULL surface, skipped draw" << std::endl;
- return;
- }
-
- int ox, oy;
- if (effect == HORIZONTAL_FLIP)
- {
- ox = sdltexture->get_texture_width() - surface->get_x() - (int) surfacepartrequest->size.x;
- }
- else
- {
- ox = surface->get_x();
- }
- if (effect == VERTICAL_FLIP)
- {
- oy = sdltexture->get_texture_height() - surface->get_y() - (int) surfacepartrequest->size.y;
- }
- else
- {
- oy = surface->get_y();
- }
-
- SDL_Rect src_rect;
- src_rect.x = (ox + (int) surfacepartrequest->source.x) * numerator / denominator;
- src_rect.y = (oy + (int) surfacepartrequest->source.y) * numerator / denominator;
- src_rect.w = (int) surfacepartrequest->size.x * numerator / denominator;
- src_rect.h = (int) surfacepartrequest->size.y * numerator / denominator;
- int dstx = (int) request.pos.x * numerator / denominator;
- int dsty = (int) request.pos.y * numerator / denominator;
- light_blit(transform, &src_rect, dstx, dsty);
- }
-
- void
- Lightmap::draw_gradient(const DrawingRequest& request)
- {
- const GradientRequest* gradientrequest
- = (GradientRequest*) request.request_data;
- const Color& top = gradientrequest->top;
- const Color& bottom = gradientrequest->bottom;
-
- int loc = 0;
- for(int y = 0;y < height;++y)
- {
- Uint8 red = (Uint8)((((float)(top.red-bottom.red)/(0-height)) * y + top.red) * 255);
- Uint8 green = (Uint8)((((float)(top.green-bottom.green)/(0-height)) * y + top.green) * 255);
- Uint8 blue = (Uint8)((((float)(top.blue-bottom.blue)/(0-height)) * y + top.blue) * 255);
- Uint8 alpha = (Uint8)((((float)(top.alpha-bottom.alpha)/(0-height)) * y + top.alpha) * 255);
- for(int x = 0;x < width;x++, loc++) {
- if(red != 0)
- {
- int redsum = red_channel[loc] + (red * alpha >> 8);
- red_channel[loc] = redsum & ~0xff ? 0xff : redsum;
- }
- if(green != 0)
- {
- int greensum = green_channel[loc] + (green * alpha >> 8);
- green_channel[loc] = greensum & ~0xff ? 0xff : greensum;
- }
- if(blue != 0)
- {
- int bluesum = blue_channel[loc] + (blue * alpha >> 8);
- blue_channel[loc] = bluesum & ~0xff ? 0xff : bluesum;
- }
- }
- }
- }
-
- void
- Lightmap::draw_filled_rect(const DrawingRequest& request)
- {
- const FillRectRequest* fillrectrequest
- = (FillRectRequest*) request.request_data;
-
- int rect_x = (int) (request.pos.x * width / SCREEN_WIDTH);
- int rect_y = (int) (request.pos.y * height / SCREEN_HEIGHT);
- int rect_w = (int) (fillrectrequest->size.x * width / SCREEN_WIDTH);
- int rect_h = (int) (fillrectrequest->size.y * height / SCREEN_HEIGHT);
- Uint8 red = (Uint8) (fillrectrequest->color.red * fillrectrequest->color.alpha * 255);
- Uint8 green = (Uint8) (fillrectrequest->color.green * fillrectrequest->color.alpha * 255);
- Uint8 blue = (Uint8) (fillrectrequest->color.blue * fillrectrequest->color.alpha * 255);
- if(red == 0 && green == 0 && blue == 0)
- {
- return;
- }
- for(int y = rect_y;y < rect_y + rect_h;y++) {
- for(int x = rect_x;x < rect_x + rect_w;x++) {
- int loc = y * width + x;
- if(red != 0)
- {
- int redsum = red_channel[loc] + red;
- red_channel[loc] = redsum & ~0xff ? 0xff : redsum;
- }
- if(green != 0)
- {
- int greensum = green_channel[loc] + green;
- green_channel[loc] = greensum & ~0xff ? 0xff : greensum;
- }
- if(blue != 0)
- {
- int bluesum = blue_channel[loc] + blue;
- blue_channel[loc] = bluesum & ~0xff ? 0xff : bluesum;
- }
- }
- }
- }
-
- void
- Lightmap::get_light(const DrawingRequest& request) const
- {
- const GetLightRequest* getlightrequest
- = (GetLightRequest*) request.request_data;
-
- int x = (int) (request.pos.x * width / SCREEN_WIDTH);
- int y = (int) (request.pos.y * height / SCREEN_HEIGHT);
- int loc = y * width + x;
- *(getlightrequest->color_ptr) = Color(((float)red_channel[loc])/255, ((float)green_channel[loc])/255, ((float)blue_channel[loc])/255);
- }
-}
+++ /dev/null
-// $Id: sdl_lightmap.hpp 4986 2007-04-16 17:48:28Z matzeb $
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#ifndef SUPERTUX_SDL_LIGHTMAP_H
-#define SUPERTUX_SDL_LIGHTMAP_H
-
-#include <SDL_video.h>
-
-#include "lightmap.hpp"
-
-class Color;
-struct DrawingRequest;
-
-namespace SDL
-{
- class Lightmap : public ::Lightmap
- {
- public:
- Lightmap();
- ~Lightmap();
-
- void start_draw(const Color &ambient_color);
- void end_draw();
- void do_draw();
- void draw_surface(const DrawingRequest& request);
- void draw_surface_part(const DrawingRequest& request);
- void draw_text(const DrawingRequest& request);
- void draw_gradient(const DrawingRequest& request);
- void draw_filled_rect(const DrawingRequest& request);
- void get_light(const DrawingRequest& request) const;
-
- private:
- SDL_Surface* screen;
- Uint8 *red_channel;
- Uint8 *blue_channel;
- Uint8 *green_channel;
- int width, height;
- int numerator, denominator;
- int LIGHTMAP_DIV;
-
- void light_blit(SDL_Surface *src, SDL_Rect *src_rect, int dstx, int dsty);
- };
-}
-
-#endif
-
+++ /dev/null
-// $Id: sdl_renderer.cpp 5063 2007-05-27 11:32:00Z matzeb $
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include <config.h>
-
-#include <functional>
-#include <algorithm>
-#include <stdexcept>
-#include <cassert>
-#include <iostream>
-#include <SDL_image.h>
-#include <sstream>
-#include <iomanip>
-#include <physfs.h>
-
-#include "glutil.hpp"
-#include "sdl_renderer.hpp"
-#include "sdl_texture.hpp"
-#include "sdl_surface_data.hpp"
-#include "drawing_context.hpp"
-#include "drawing_request.hpp"
-#include "surface.hpp"
-#include "font.hpp"
-#include "main.hpp"
-#include "gameconfig.hpp"
-#include "log.hpp"
-#include "texture.hpp"
-#include "texture_manager.hpp"
-#include "obstack/obstackpp.hpp"
-
-namespace
-{
- SDL_Surface *apply_alpha(SDL_Surface *src, float alpha_factor)
- {
- // FIXME: This is really slow
- assert(src->format->Amask);
- int alpha = (int) (alpha_factor * 256);
- SDL_Surface *dst = SDL_CreateRGBSurface(src->flags, src->w, src->h, src->format->BitsPerPixel, src->format->Rmask, src->format->Gmask, src->format->Bmask, src->format->Amask);
- int bpp = dst->format->BytesPerPixel;
- if(SDL_MUSTLOCK(src))
- {
- SDL_LockSurface(src);
- }
- if(SDL_MUSTLOCK(dst))
- {
- SDL_LockSurface(dst);
- }
- for(int y = 0;y < dst->h;y++) {
- for(int x = 0;x < dst->w;x++) {
- Uint8 *srcpixel = (Uint8 *) src->pixels + y * src->pitch + x * bpp;
- Uint8 *dstpixel = (Uint8 *) dst->pixels + y * dst->pitch + x * bpp;
- Uint32 mapped = 0;
- switch(bpp) {
- case 1:
- mapped = *srcpixel;
- break;
- case 2:
- mapped = *(Uint16 *)srcpixel;
- break;
- case 3:
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- mapped |= srcpixel[0] << 16;
- mapped |= srcpixel[1] << 8;
- mapped |= srcpixel[2] << 0;
-#else
- mapped |= srcpixel[0] << 0;
- mapped |= srcpixel[1] << 8;
- mapped |= srcpixel[2] << 16;
-#endif
- break;
- case 4:
- mapped = *(Uint32 *)srcpixel;
- break;
- }
- Uint8 r, g, b, a;
- SDL_GetRGBA(mapped, src->format, &r, &g, &b, &a);
- mapped = SDL_MapRGBA(dst->format, r, g, b, (a * alpha) >> 8);
- switch(bpp) {
- case 1:
- *dstpixel = mapped;
- break;
- case 2:
- *(Uint16 *)dstpixel = mapped;
- break;
- case 3:
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- dstpixel[0] = (mapped >> 16) & 0xff;
- dstpixel[1] = (mapped >> 8) & 0xff;
- dstpixel[2] = (mapped >> 0) & 0xff;
-#else
- dstpixel[0] = (mapped >> 0) & 0xff;
- dstpixel[1] = (mapped >> 8) & 0xff;
- dstpixel[2] = (mapped >> 16) & 0xff;
-#endif
- break;
- case 4:
- *(Uint32 *)dstpixel = mapped;
- break;
- }
- }
- }
- if(SDL_MUSTLOCK(dst))
- {
- SDL_UnlockSurface(dst);
- }
- if(SDL_MUSTLOCK(src))
- {
- SDL_UnlockSurface(src);
- }
- return dst;
- }
-}
-
-namespace SDL
-{
- Renderer::Renderer()
- {
- ::Renderer::instance_ = this;
-
- const SDL_VideoInfo *info = SDL_GetVideoInfo();
- log_info << "Hardware surfaces are " << (info->hw_available ? "" : "not ") << "available." << std::endl;
- log_info << "Hardware to hardware blits are " << (info->blit_hw ? "" : "not ") << "accelerated." << std::endl;
- log_info << "Hardware to hardware blits with colorkey are " << (info->blit_hw_CC ? "" : "not ") << "accelerated." << std::endl;
- log_info << "Hardware to hardware blits with alpha are " << (info->blit_hw_A ? "" : "not ") << "accelerated." << std::endl;
- log_info << "Software to hardware blits are " << (info->blit_sw ? "" : "not ") << "accelerated." << std::endl;
- log_info << "Software to hardware blits with colorkey are " << (info->blit_sw_CC ? "" : "not ") << "accelerated." << std::endl;
- log_info << "Software to hardware blits with alpha are " << (info->blit_sw_A ? "" : "not ") << "accelerated." << std::endl;
- log_info << "Color fills are " << (info->blit_fill ? "" : "not ") << "accelerated." << std::endl;
-
- int flags = SDL_SWSURFACE | SDL_ANYFORMAT;
- if(config->use_fullscreen)
- flags |= SDL_FULLSCREEN;
-
- int width = 800; //FIXME: config->screenwidth;
- int height = 600; //FIXME: config->screenheight;
-
- screen = SDL_SetVideoMode(width, height, 0, flags);
- if(screen == 0) {
- std::stringstream msg;
- msg << "Couldn't set video mode (" << width << "x" << height
- << "): " << SDL_GetError();
- throw std::runtime_error(msg.str());
- }
-
- numerator = 1;
- denominator = 1;
- /* FIXME:
- float xfactor = (float) config->screenwidth / SCREEN_WIDTH;
- float yfactor = (float) config->screenheight / SCREEN_HEIGHT;
- if(xfactor < yfactor)
- {
- numerator = config->screenwidth;
- denominator = SCREEN_WIDTH;
- }
- else
- {
- numerator = config->screenheight;
- denominator = SCREEN_HEIGHT;
- }
- */
- if(texture_manager == 0)
- texture_manager = new TextureManager();
- }
-
- Renderer::~Renderer()
- {
- }
-
- void
- Renderer::draw_surface(const DrawingRequest& request)
- {
- //FIXME: support parameters request.alpha, request.angle, request.blend
- const Surface* surface = (const Surface*) request.request_data;
- SDL::Texture *sdltexture = dynamic_cast<SDL::Texture *>(surface->get_texture());
- SDL::SurfaceData *surface_data = reinterpret_cast<SDL::SurfaceData *>(surface->get_surface_data());
-
- DrawingEffect effect = request.drawing_effect;
- if (surface->get_flipx()) effect = HORIZONTAL_FLIP;
-
- SDL_Surface *transform = sdltexture->get_transform(request.color, effect);
-
- // get and check SDL_Surface
- if (transform == 0) {
- std::cerr << "Warning: Tried to draw NULL surface, skipped draw" << std::endl;
- return;
- }
-
- SDL_Rect *src_rect = surface_data->get_src_rect(effect);
- SDL_Rect dst_rect;
- dst_rect.x = (int) request.pos.x * numerator / denominator;
- dst_rect.y = (int) request.pos.y * numerator / denominator;
-
- Uint8 alpha = 0;
- if(request.alpha != 1.0)
- {
- if(!transform->format->Amask)
- {
- if(transform->flags & SDL_SRCALPHA)
- {
- alpha = transform->format->alpha;
- }
- else
- {
- alpha = 255;
- }
- SDL_SetAlpha(transform, SDL_SRCALPHA, (Uint8) (request.alpha * alpha));
- }
- /*else
- {
- transform = apply_alpha(transform, request.alpha);
- }*/
- }
-
- SDL_BlitSurface(transform, src_rect, screen, &dst_rect);
-
- if(request.alpha != 1.0)
- {
- if(!transform->format->Amask)
- {
- if(alpha == 255)
- {
- SDL_SetAlpha(transform, SDL_RLEACCEL, 0);
- }
- else
- {
- SDL_SetAlpha(transform, SDL_SRCALPHA | SDL_RLEACCEL, alpha);
- }
- }
- /*else
- {
- SDL_FreeSurface(transform);
- }*/
- }
- }
-
- void
- Renderer::draw_surface_part(const DrawingRequest& request)
- {
- const SurfacePartRequest* surfacepartrequest
- = (SurfacePartRequest*) request.request_data;
-
- const Surface* surface = surfacepartrequest->surface;
- SDL::Texture *sdltexture = dynamic_cast<SDL::Texture *>(surface->get_texture());
-
- DrawingEffect effect = request.drawing_effect;
- if (surface->get_flipx()) effect = HORIZONTAL_FLIP;
-
- SDL_Surface *transform = sdltexture->get_transform(request.color, effect);
-
- // get and check SDL_Surface
- if (transform == 0) {
- std::cerr << "Warning: Tried to draw NULL surface, skipped draw" << std::endl;
- return;
- }
-
- int ox, oy;
- if (effect == HORIZONTAL_FLIP)
- {
- ox = sdltexture->get_texture_width() - surface->get_x() - (int) surfacepartrequest->size.x;
- }
- else
- {
- ox = surface->get_x();
- }
- if (effect == VERTICAL_FLIP)
- {
- oy = sdltexture->get_texture_height() - surface->get_y() - (int) surfacepartrequest->size.y;
- }
- else
- {
- oy = surface->get_y();
- }
-
- SDL_Rect src_rect;
- src_rect.x = (ox + (int) surfacepartrequest->source.x) * numerator / denominator;
- src_rect.y = (oy + (int) surfacepartrequest->source.y) * numerator / denominator;
- src_rect.w = (int) surfacepartrequest->size.x * numerator / denominator;
- src_rect.h = (int) surfacepartrequest->size.y * numerator / denominator;
-
- SDL_Rect dst_rect;
- dst_rect.x = (int) request.pos.x * numerator / denominator;
- dst_rect.y = (int) request.pos.y * numerator / denominator;
-
- Uint8 alpha = 0;
- if(request.alpha != 1.0)
- {
- if(!transform->format->Amask)
- {
- if(transform->flags & SDL_SRCALPHA)
- {
- alpha = transform->format->alpha;
- }
- else
- {
- alpha = 255;
- }
- SDL_SetAlpha(transform, SDL_SRCALPHA, (Uint8) (request.alpha * alpha));
- }
- /*else
- {
- transform = apply_alpha(transform, request.alpha);
- }*/
- }
-
- SDL_BlitSurface(transform, &src_rect, screen, &dst_rect);
-
- if(request.alpha != 1.0)
- {
- if(!transform->format->Amask)
- {
- if(alpha == 255)
- {
- SDL_SetAlpha(transform, SDL_RLEACCEL, 0);
- }
- else
- {
- SDL_SetAlpha(transform, SDL_SRCALPHA | SDL_RLEACCEL, alpha);
- }
- }
- /*else
- {
- SDL_FreeSurface(transform);
- }*/
- }
- }
-
- void
- Renderer::draw_gradient(const DrawingRequest& request)
- {
- const GradientRequest* gradientrequest
- = (GradientRequest*) request.request_data;
- const Color& top = gradientrequest->top;
- const Color& bottom = gradientrequest->bottom;
-
- for(int y = 0;y < screen->h;++y)
- {
- Uint8 r = (Uint8)((((float)(top.red-bottom.red)/(0-screen->h)) * y + top.red) * 255);
- Uint8 g = (Uint8)((((float)(top.green-bottom.green)/(0-screen->h)) * y + top.green) * 255);
- Uint8 b = (Uint8)((((float)(top.blue-bottom.blue)/(0-screen->h)) * y + top.blue) * 255);
- Uint8 a = (Uint8)((((float)(top.alpha-bottom.alpha)/(0-screen->h)) * y + top.alpha) * 255);
- Uint32 color = SDL_MapRGB(screen->format, r, g, b);
-
- SDL_Rect rect;
- rect.x = 0;
- rect.y = y;
- rect.w = screen->w;
- rect.h = 1;
-
- if(a == SDL_ALPHA_OPAQUE) {
- SDL_FillRect(screen, &rect, color);
- } else if(a != SDL_ALPHA_TRANSPARENT) {
- SDL_Surface *temp = SDL_CreateRGBSurface(screen->flags, rect.w, rect.h, screen->format->BitsPerPixel, screen->format->Rmask, screen->format->Gmask, screen->format->Bmask, screen->format->Amask);
-
- SDL_FillRect(temp, 0, color);
- SDL_SetAlpha(temp, SDL_SRCALPHA | SDL_RLEACCEL, a);
- SDL_BlitSurface(temp, 0, screen, &rect);
- SDL_FreeSurface(temp);
- }
- }
- }
-
- void
- Renderer::draw_filled_rect(const DrawingRequest& request)
- {
- const FillRectRequest* fillrectrequest
- = (FillRectRequest*) request.request_data;
-
- SDL_Rect rect;
- rect.x = (Sint16)request.pos.x * screen->w / SCREEN_WIDTH;
- rect.y = (Sint16)request.pos.y * screen->h / SCREEN_HEIGHT;
- rect.w = (Uint16)fillrectrequest->size.x * screen->w / SCREEN_WIDTH;
- rect.h = (Uint16)fillrectrequest->size.y * screen->h / SCREEN_HEIGHT;
- Uint8 r = static_cast<Uint8>(fillrectrequest->color.red * 255);
- Uint8 g = static_cast<Uint8>(fillrectrequest->color.green * 255);
- Uint8 b = static_cast<Uint8>(fillrectrequest->color.blue * 255);
- Uint8 a = static_cast<Uint8>(fillrectrequest->color.alpha * 255);
- Uint32 color = SDL_MapRGB(screen->format, r, g, b);
- if(a == SDL_ALPHA_OPAQUE) {
- SDL_FillRect(screen, &rect, color);
- } else if(a != SDL_ALPHA_TRANSPARENT) {
- SDL_Surface *temp = SDL_CreateRGBSurface(screen->flags, rect.w, rect.h, screen->format->BitsPerPixel, screen->format->Rmask, screen->format->Gmask, screen->format->Bmask, screen->format->Amask);
-
- SDL_FillRect(temp, 0, color);
- SDL_SetAlpha(temp, SDL_SRCALPHA | SDL_RLEACCEL, a);
- SDL_BlitSurface(temp, 0, screen, &rect);
- SDL_FreeSurface(temp);
- }
- }
-
- void
- Renderer::draw_inverse_ellipse(const DrawingRequest&)
- {
- }
-
- void
- Renderer::do_take_screenshot()
- {
- // [Christoph] TODO: Yes, this method also takes care of the actual disk I/O. Split it?
-
- SDL_Surface *screen = SDL_GetVideoSurface();
-
- // save screenshot
- static const std::string writeDir = PHYSFS_getWriteDir();
- static const std::string dirSep = PHYSFS_getDirSeparator();
- static const std::string baseName = "screenshot";
- static const std::string fileExt = ".bmp";
- std::string fullFilename;
- for (int num = 0; num < 1000; num++) {
- std::ostringstream oss;
- oss << baseName;
- oss << std::setw(3) << std::setfill('0') << num;
- oss << fileExt;
- std::string fileName = oss.str();
- fullFilename = writeDir + dirSep + fileName;
- if (!PHYSFS_exists(fileName.c_str())) {
- SDL_SaveBMP(screen, fullFilename.c_str());
- log_debug << "Wrote screenshot to \"" << fullFilename << "\"" << std::endl;
- return;
- }
- }
- log_warning << "Did not save screenshot, because all files up to \"" << fullFilename << "\" already existed" << std::endl;
- }
-
- void
- Renderer::flip()
- {
- SDL_Flip(screen);
- }
-
- void
- Renderer::resize(int, int)
- {
-
- }
-}
+++ /dev/null
-// $Id: sdl_renderer.hpp 4986 2007-04-16 17:48:28Z matzeb $
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#ifndef SUPERTUX_SDL_RENDERER_H
-#define SUPERTUX_SDL_RENDERER_H
-
-#include <SDL_video.h>
-
-#include "renderer.hpp"
-
-namespace SDL
-{
- class Renderer : public ::Renderer
- {
- public:
- Renderer();
- ~Renderer();
-
- void draw_surface(const DrawingRequest& request);
- void draw_surface_part(const DrawingRequest& request);
- void draw_text(const DrawingRequest& request);
- void draw_gradient(const DrawingRequest& request);
- void draw_filled_rect(const DrawingRequest& request);
- void draw_inverse_ellipse(const DrawingRequest& request);
- void do_take_screenshot();
- void flip();
- void resize(int w, int h);
- void apply_config() {}
- private:
- SDL_Surface *screen;
- int numerator, denominator;
- };
-}
-
-#endif
-
+++ /dev/null
-// $Id: gl_surface_data.hpp 4063 2006-07-21 21:05:23Z anmaster $
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#ifndef __SDL_SURFACE_DATA_HPP__
-#define __SDL_SURFACE_DATA_HPP__
-
-#include <config.h>
-
-#include "surface.hpp"
-#include "texture.hpp"
-#include "main.hpp"
-#include "gameconfig.hpp"
-
-namespace SDL
-{
- class SurfaceData
- {
- private:
- const Surface &surface;
- SDL_Rect src_rects[NUM_EFFECTS];
-
- public:
- SurfaceData(const Surface &surface) :
- surface(surface)
- {
- int numerator = 1;
- int denominator = 1;
- //float xfactor = 1.0f; // FIXME: (float) config->screenwidth / SCREEN_WIDTH;
- //float yfactor = 1.0f; // FIXME: (float) config->screenheight / SCREEN_HEIGHT;
-
- /* FIXME:
- if(xfactor < yfactor)
- {
- numerator = config->screenwidth;
- denominator = SCREEN_WIDTH;
- }
- else
- {
- numerator = config->screenheight;
- denominator = SCREEN_HEIGHT;
- }
- */
-
- src_rects[NO_EFFECT].x = surface.get_x() * numerator / denominator;
- src_rects[NO_EFFECT].y = surface.get_y() * numerator / denominator;
- src_rects[NO_EFFECT].w = surface.get_width() * numerator / denominator;
- src_rects[NO_EFFECT].h = surface.get_height() * numerator / denominator;
-
- int flipped_x = surface.get_texture()->get_texture_width() - surface.get_x() - surface.get_width();
- src_rects[HORIZONTAL_FLIP].x = flipped_x * numerator / denominator;
- src_rects[HORIZONTAL_FLIP].y = surface.get_y() * numerator / denominator;
- src_rects[HORIZONTAL_FLIP].w = surface.get_width() * numerator / denominator;
- src_rects[HORIZONTAL_FLIP].h = surface.get_height() * numerator / denominator;
-
- int flipped_y = surface.get_texture()->get_texture_height() - surface.get_y() - surface.get_height();
- src_rects[VERTICAL_FLIP].x = flipped_y * numerator / denominator;
- src_rects[VERTICAL_FLIP].y = surface.get_y() * numerator / denominator;
- src_rects[VERTICAL_FLIP].w = surface.get_width() * numerator / denominator;
- src_rects[VERTICAL_FLIP].h = surface.get_height() * numerator / denominator;
- }
-
- SDL_Rect *get_src_rect(DrawingEffect effect)
- {
- return src_rects + effect;
- }
- };
-}
-
-#endif
+++ /dev/null
-// $Id: sdl_texture.cpp 4063 2006-07-21 21:05:23Z anmaster $
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
-
-#include "sdl_texture.hpp"
-#include "color.hpp"
-#include "gameconfig.hpp"
-#include "main.hpp"
-
-#include <assert.h>
-
-#include <SDL.h>
-
-namespace
-{
-#define BILINEAR
-
-#ifdef NAIVE
- SDL_Surface *scale(SDL_Surface *src, int numerator, int denominator)
- {
- if(numerator == denominator)
- {
- src->refcount++;
- return src;
- }
- else
- {
- SDL_Surface *dst = SDL_CreateRGBSurface(src->flags, src->w * numerator / denominator, src->h * numerator / denominator, src->format->BitsPerPixel, src->format->Rmask, src->format->Gmask, src->format->Bmask, src->format->Amask);
- int bpp = dst->format->BytesPerPixel;
- if(SDL_MUSTLOCK(src))
- {
- SDL_LockSurface(src);
- }
- if(SDL_MUSTLOCK(dst))
- {
- SDL_LockSurface(dst);
- }
- for(int y = 0;y < dst->h;y++) {
- for(int x = 0;x < dst->w;x++) {
- Uint8 *srcpixel = (Uint8 *) src->pixels + (y * denominator / numerator) * src->pitch + (x * denominator / numerator) * bpp;
- Uint8 *dstpixel = (Uint8 *) dst->pixels + y * dst->pitch + x * bpp;
- switch(bpp) {
- case 4:
- dstpixel[3] = srcpixel[3];
- case 3:
- dstpixel[2] = srcpixel[2];
- case 2:
- dstpixel[1] = srcpixel[1];
- case 1:
- dstpixel[0] = srcpixel[0];
- }
- }
- }
- if(SDL_MUSTLOCK(dst))
- {
- SDL_UnlockSurface(dst);
- }
- if(SDL_MUSTLOCK(src))
- {
- SDL_UnlockSurface(src);
- }
- if(!src->format->Amask)
- {
- if(src->flags & SDL_SRCALPHA)
- {
- SDL_SetAlpha(dst, SDL_SRCALPHA | SDL_RLEACCEL, src->format->alpha);
- }
- if(src->flags & SDL_SRCCOLORKEY)
- {
- SDL_SetColorKey(dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, src->format->colorkey);
- }
- }
- return dst;
- }
- }
-#endif
-
-#ifdef BILINEAR
- void getpixel(SDL_Surface *src, int srcx, int srcy, Uint8 color[4])
- {
- int bpp = src->format->BytesPerPixel;
- if(srcx == src->w)
- {
- srcx--;
- }
- if(srcy == src->h)
- {
- srcy--;
- }
- Uint8 *srcpixel = (Uint8 *) src->pixels + srcy * src->pitch + srcx * bpp;
- Uint32 mapped = 0;
- switch(bpp) {
- case 1:
- mapped = *srcpixel;
- break;
- case 2:
- mapped = *(Uint16 *)srcpixel;
- break;
- case 3:
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- mapped |= srcpixel[0] << 16;
- mapped |= srcpixel[1] << 8;
- mapped |= srcpixel[2] << 0;
-#else
- mapped |= srcpixel[0] << 0;
- mapped |= srcpixel[1] << 8;
- mapped |= srcpixel[2] << 16;
-#endif
- break;
- case 4:
- mapped = *(Uint32 *)srcpixel;
- break;
- }
- SDL_GetRGBA(mapped, src->format, &color[0], &color[1], &color[2], &color[3]);
- }
-
- void merge(Uint8 color[4], Uint8 color0[4], Uint8 color1[4], int rem, int total)
- {
- color[0] = (color0[0] * (total - rem) + color1[0] * rem) / total;
- color[1] = (color0[1] * (total - rem) + color1[1] * rem) / total;
- color[2] = (color0[2] * (total - rem) + color1[2] * rem) / total;
- color[3] = (color0[3] * (total - rem) + color1[3] * rem) / total;
- }
-
- SDL_Surface *scale(SDL_Surface *src, int numerator, int denominator)
- {
- if(numerator == denominator)
- {
- src->refcount++;
- return src;
- }
- else
- {
- SDL_Surface *dst = SDL_CreateRGBSurface(src->flags, src->w * numerator / denominator, src->h * numerator / denominator, src->format->BitsPerPixel, src->format->Rmask, src->format->Gmask, src->format->Bmask, src->format->Amask);
- int bpp = dst->format->BytesPerPixel;
- if(SDL_MUSTLOCK(src))
- {
- SDL_LockSurface(src);
- }
- if(SDL_MUSTLOCK(dst))
- {
- SDL_LockSurface(dst);
- }
- for(int y = 0;y < dst->h;y++) {
- for(int x = 0;x < dst->w;x++) {
- int srcx = x * denominator / numerator;
- int srcy = y * denominator / numerator;
- Uint8 color00[4], color01[4], color10[4], color11[4];
- getpixel(src, srcx, srcy, color00);
- getpixel(src, srcx + 1, srcy, color01);
- getpixel(src, srcx, srcy + 1, color10);
- getpixel(src, srcx + 1, srcy + 1, color11);
- Uint8 color0[4], color1[4], color[4];
- int remx = x * denominator % numerator;
- merge(color0, color00, color01, remx, numerator);
- merge(color1, color10, color11, remx, numerator);
- int remy = y * denominator % numerator;
- merge(color, color0, color1, remy, numerator);
- Uint8 *dstpixel = (Uint8 *) dst->pixels + y * dst->pitch + x * bpp;
- Uint32 mapped = SDL_MapRGBA(dst->format, color[0], color[1], color[2], color[3]);
- switch(bpp) {
- case 1:
- *dstpixel = mapped;
- break;
- case 2:
- *(Uint16 *)dstpixel = mapped;
- break;
- case 3:
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- dstpixel[0] = (mapped >> 16) & 0xff;
- dstpixel[1] = (mapped >> 8) & 0xff;
- dstpixel[2] = (mapped >> 0) & 0xff;
-#else
- dstpixel[0] = (mapped >> 0) & 0xff;
- dstpixel[1] = (mapped >> 8) & 0xff;
- dstpixel[2] = (mapped >> 16) & 0xff;
-#endif
- break;
- case 4:
- *(Uint32 *)dstpixel = mapped;
- break;
- }
- }
- }
- if(SDL_MUSTLOCK(dst))
- {
- SDL_UnlockSurface(dst);
- }
- if(SDL_MUSTLOCK(src))
- {
- SDL_UnlockSurface(src);
- }
- if(!src->format->Amask)
- {
- if(src->flags & SDL_SRCALPHA)
- {
- SDL_SetAlpha(dst, SDL_SRCALPHA | SDL_RLEACCEL, src->format->alpha);
- }
- if(src->flags & SDL_SRCCOLORKEY)
- {
- SDL_SetColorKey(dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, src->format->colorkey);
- }
- }
- return dst;
- }
- }
-#endif
-
- SDL_Surface *horz_flip(SDL_Surface *src)
- {
- SDL_Surface *dst = SDL_CreateRGBSurface(src->flags, src->w, src->h, src->format->BitsPerPixel, src->format->Rmask, src->format->Gmask, src->format->Bmask, src->format->Amask);
- int bpp = dst->format->BytesPerPixel;
- if(SDL_MUSTLOCK(src))
- {
- SDL_LockSurface(src);
- }
- if(SDL_MUSTLOCK(dst))
- {
- SDL_LockSurface(dst);
- }
- for(int y = 0;y < dst->h;y++) {
- for(int x = 0;x < dst->w;x++) {
- Uint8 *srcpixel = (Uint8 *) src->pixels + y * src->pitch + x * bpp;
- Uint8 *dstpixel = (Uint8 *) dst->pixels + y * dst->pitch + (dst->w - x - 1) * bpp;
- switch(bpp) {
- case 4:
- dstpixel[3] = srcpixel[3];
- case 3:
- dstpixel[2] = srcpixel[2];
- case 2:
- dstpixel[1] = srcpixel[1];
- case 1:
- dstpixel[0] = srcpixel[0];
- }
- }
- }
- if(SDL_MUSTLOCK(dst))
- {
- SDL_UnlockSurface(dst);
- }
- if(SDL_MUSTLOCK(src))
- {
- SDL_UnlockSurface(src);
- }
- if(!src->format->Amask)
- {
- if(src->flags & SDL_SRCALPHA)
- {
- SDL_SetAlpha(dst, SDL_SRCALPHA | SDL_RLEACCEL, src->format->alpha);
- }
- if(src->flags & SDL_SRCCOLORKEY)
- {
- SDL_SetColorKey(dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, src->format->colorkey);
- }
- }
- return dst;
- }
-
- SDL_Surface *vert_flip(SDL_Surface *src)
- {
- SDL_Surface *dst = SDL_CreateRGBSurface(src->flags, src->w, src->h, src->format->BitsPerPixel, src->format->Rmask, src->format->Gmask, src->format->Bmask, src->format->Amask);
- int bpp = dst->format->BytesPerPixel;
- if(SDL_MUSTLOCK(src))
- {
- SDL_LockSurface(src);
- }
- if(SDL_MUSTLOCK(dst))
- {
- SDL_LockSurface(dst);
- }
- for(int y = 0;y < dst->h;y++) {
- for(int x = 0;x < dst->w;x++) {
- Uint8 *srcpixel = (Uint8 *) src->pixels + y * src->pitch + x * bpp;
- Uint8 *dstpixel = (Uint8 *) dst->pixels + (dst->h - y - 1) * dst->pitch + x * bpp;
- switch(bpp) {
- case 4:
- dstpixel[3] = srcpixel[3];
- case 3:
- dstpixel[2] = srcpixel[2];
- case 2:
- dstpixel[1] = srcpixel[1];
- case 1:
- dstpixel[0] = srcpixel[0];
- }
- }
- }
- if(SDL_MUSTLOCK(dst))
- {
- SDL_UnlockSurface(dst);
- }
- if(SDL_MUSTLOCK(src))
- {
- SDL_UnlockSurface(src);
- }
- if(!src->format->Amask)
- {
- if(src->flags & SDL_SRCALPHA)
- {
- SDL_SetAlpha(dst, SDL_SRCALPHA | SDL_RLEACCEL, src->format->alpha);
- }
- if(src->flags & SDL_SRCCOLORKEY)
- {
- SDL_SetColorKey(dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, src->format->colorkey);
- }
- }
- return dst;
- }
-
- SDL_Surface *colorize(SDL_Surface *src, const Color &color)
- {
- // FIXME: This is really slow
- assert(color.red != 1.0 || color.green != 1.0 || color.blue != 1.0);
- int red = (int) (color.red * 256);
- int green = (int) (color.green * 256);
- int blue = (int) (color.blue * 256);
- SDL_Surface *dst = SDL_CreateRGBSurface(src->flags, src->w, src->h, src->format->BitsPerPixel, src->format->Rmask, src->format->Gmask, src->format->Bmask, src->format->Amask);
- int bpp = dst->format->BytesPerPixel;
- if(SDL_MUSTLOCK(src))
- {
- SDL_LockSurface(src);
- }
- if(SDL_MUSTLOCK(dst))
- {
- SDL_LockSurface(dst);
- }
- for(int y = 0;y < dst->h;y++) {
- for(int x = 0;x < dst->w;x++) {
- Uint8 *srcpixel = (Uint8 *) src->pixels + y * src->pitch + x * bpp;
- Uint8 *dstpixel = (Uint8 *) dst->pixels + y * dst->pitch + x * bpp;
- Uint32 mapped = 0;
- switch(bpp) {
- case 1:
- mapped = *srcpixel;
- break;
- case 2:
- mapped = *(Uint16 *)srcpixel;
- break;
- case 3:
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- mapped |= srcpixel[0] << 16;
- mapped |= srcpixel[1] << 8;
- mapped |= srcpixel[2] << 0;
-#else
- mapped |= srcpixel[0] << 0;
- mapped |= srcpixel[1] << 8;
- mapped |= srcpixel[2] << 16;
-#endif
- break;
- case 4:
- mapped = *(Uint32 *)srcpixel;
- break;
- }
- if(src->format->Amask || !(src->flags & SDL_SRCCOLORKEY) || mapped != src->format->colorkey)
- {
- Uint8 r, g, b, a;
- SDL_GetRGBA(mapped, src->format, &r, &g, &b, &a);
- mapped = SDL_MapRGBA(dst->format, (r * red) >> 8, (g * green) >> 8, (b * blue) >> 8, a);
- }
- switch(bpp) {
- case 1:
- *dstpixel = mapped;
- break;
- case 2:
- *(Uint16 *)dstpixel = mapped;
- break;
- case 3:
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- dstpixel[0] = (mapped >> 16) & 0xff;
- dstpixel[1] = (mapped >> 8) & 0xff;
- dstpixel[2] = (mapped >> 0) & 0xff;
-#else
- dstpixel[0] = (mapped >> 0) & 0xff;
- dstpixel[1] = (mapped >> 8) & 0xff;
- dstpixel[2] = (mapped >> 16) & 0xff;
-#endif
- break;
- case 4:
- *(Uint32 *)dstpixel = mapped;
- break;
- }
- }
- }
- if(SDL_MUSTLOCK(dst))
- {
- SDL_UnlockSurface(dst);
- }
- if(SDL_MUSTLOCK(src))
- {
- SDL_UnlockSurface(src);
- }
- if(!src->format->Amask)
- {
- if(src->flags & SDL_SRCALPHA)
- {
- SDL_SetAlpha(dst, SDL_SRCALPHA | SDL_RLEACCEL, src->format->alpha);
- }
- if(src->flags & SDL_SRCCOLORKEY)
- {
- SDL_SetColorKey(dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, src->format->colorkey);
- }
- }
- return dst;
- }
-
- SDL_Surface *optimize(SDL_Surface *src)
- {
- if(!src->format->Amask)
- {
- return SDL_DisplayFormat(src);
- }
- else
- {
- int transparent = 0;
- int opaque = 0;
- int semitransparent = 0;
- int alphasum = 0;
- int squaredalphasum = 0;
- bool colors[(1 << 12)];
- memset(colors, 0, (1 << 12) * sizeof(bool));
-
- int bpp = src->format->BytesPerPixel;
- if(SDL_MUSTLOCK(src))
- {
- SDL_LockSurface(src);
- }
- for(int y = 0;y < src->h;y++) {
- for(int x = 0;x < src->w;x++) {
- Uint8 *pixel = (Uint8 *) src->pixels + y * src->pitch + x * bpp;
- Uint32 mapped = 0;
- switch(bpp) {
- case 1:
- mapped = *pixel;
- break;
- case 2:
- mapped = *(Uint16 *)pixel;
- break;
- case 3:
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- mapped |= pixel[0] << 16;
- mapped |= pixel[1] << 8;
- mapped |= pixel[2] << 0;
-#else
- mapped |= pixel[0] << 0;
- mapped |= pixel[1] << 8;
- mapped |= pixel[2] << 16;
-#endif
- break;
- case 4:
- mapped = *(Uint32 *)pixel;
- break;
- }
- Uint8 red, green, blue, alpha;
- SDL_GetRGBA(mapped, src->format, &red, &green, &blue, &alpha);
- if(alpha < 16)
- {
- transparent++;
- }
- else if (alpha > 240)
- {
- opaque++;
- alphasum += alpha;
- squaredalphasum += alpha * alpha;
- }
- else
- {
- semitransparent++;
- squaredalphasum += alpha * alpha;
- }
- if(alpha != 0)
- {
- colors[((red & 0xf0) << 4) | (green & 0xf0) | ((blue & 0xf0) >> 4)] = true;
- }
- }
- }
- if(SDL_MUSTLOCK(src))
- {
- SDL_UnlockSurface(src);
- }
- int avgalpha = (opaque + semitransparent) ? alphasum / (opaque + semitransparent) : 0;
- int avgsquaredalpha = (opaque + semitransparent) ? squaredalphasum / (opaque + semitransparent) : 0;
- int alphavariance = avgsquaredalpha - avgalpha * avgalpha;
- if(semitransparent > ((transparent + opaque + semitransparent) / 8) && alphavariance > 16)
- {
- return SDL_DisplayFormatAlpha(src);
- }
- int keycolor = -1;
- for(int i = 0;i < (1 << 12);i++)
- {
- if(!colors[i])
- {
- keycolor = i;
- }
- }
- if(keycolor == -1)
- {
- return SDL_DisplayFormatAlpha(src);
- }
- SDL_Surface *dst = SDL_CreateRGBSurface(src->flags & ~(SDL_SRCALPHA), src->w, src->h, src->format->BitsPerPixel, src->format->Rmask, src->format->Gmask, src->format->Bmask, 0);
- bpp = dst->format->BytesPerPixel;
- Uint32 key = SDL_MapRGB(dst->format, (((keycolor & 0xf00) >> 4) | 0xf), ((keycolor & 0xf0) | 0xf), (((keycolor & 0xf) << 4) | 0xf));
- if(SDL_MUSTLOCK(src))
- {
- SDL_LockSurface(src);
- }
- if(SDL_MUSTLOCK(dst))
- {
- SDL_LockSurface(dst);
- }
- for(int y = 0;y < dst->h;y++) {
- for(int x = 0;x < dst->w;x++) {
- Uint8 *srcpixel = (Uint8 *) src->pixels + y * src->pitch + x * bpp;
- Uint8 *dstpixel = (Uint8 *) dst->pixels + y * dst->pitch + x * bpp;
- Uint32 mapped = 0;
- switch(bpp) {
- case 1:
- mapped = *srcpixel;
- break;
- case 2:
- mapped = *(Uint16 *)srcpixel;
- break;
- case 3:
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- mapped |= srcpixel[0] << 16;
- mapped |= srcpixel[1] << 8;
- mapped |= srcpixel[2] << 0;
-#else
- mapped |= srcpixel[0] << 0;
- mapped |= srcpixel[1] << 8;
- mapped |= srcpixel[2] << 16;
-#endif
- break;
- case 4:
- mapped = *(Uint32 *)srcpixel;
- break;
- }
- Uint8 red, green, blue, alpha;
- SDL_GetRGBA(mapped, src->format, &red, &green, &blue, &alpha);
- if(alpha < (avgalpha / 4))
- {
- mapped = key;
- }
- else
- {
- mapped = SDL_MapRGB(dst->format, red, green, blue);
- }
- switch(bpp) {
- case 1:
- *dstpixel = mapped;
- break;
- case 2:
- *(Uint16 *)dstpixel = mapped;
- break;
- case 3:
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- dstpixel[0] = (mapped >> 16) & 0xff;
- dstpixel[1] = (mapped >> 8) & 0xff;
- dstpixel[2] = (mapped >> 0) & 0xff;
-#else
- dstpixel[0] = (mapped >> 0) & 0xff;
- dstpixel[1] = (mapped >> 8) & 0xff;
- dstpixel[2] = (mapped >> 16) & 0xff;
-#endif
- break;
- case 4:
- *(Uint32 *)dstpixel = mapped;
- break;
- }
- }
- }
- if(SDL_MUSTLOCK(dst))
- {
- SDL_UnlockSurface(dst);
- }
- if(SDL_MUSTLOCK(src))
- {
- SDL_UnlockSurface(src);
- }
- if(avgalpha < 240)
- {
- SDL_SetAlpha(dst, SDL_SRCALPHA | SDL_RLEACCEL, avgalpha);
- }
- SDL_SetColorKey(dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, key);
- SDL_Surface *convert = SDL_DisplayFormat(dst);
- SDL_FreeSurface(dst);
- return convert;
- }
- }
-}
-
-namespace SDL
-{
- Texture::Texture(SDL_Surface* image)
- {
- texture = optimize(image);
- //width = texture->w;
- //height = texture->h;
- int numerator = 1;
- int denominator = 1;
- //FIXME: float xfactor = (float) config->screenwidth / SCREEN_WIDTH;
- //FIXME: float yfactor = (float) config->screenheight / SCREEN_HEIGHT;
- /* FIXME:
- if(xfactor < yfactor)
- {
- numerator = config->screenwidth;
- denominator = SCREEN_WIDTH;
- }
- else
- {
- numerator = config->screenheight;
- denominator = SCREEN_HEIGHT;
- }
- */
- cache[NO_EFFECT][Color::WHITE] = scale(texture, numerator, denominator);
- }
-
- Texture::~Texture()
- {
- SDL_FreeSurface(texture);
- }
-
- SDL_Surface *Texture::get_transform(const Color &color, DrawingEffect effect)
- {
- if(cache[NO_EFFECT][color] == 0) {
- assert(cache[NO_EFFECT][Color::WHITE]);
- cache[NO_EFFECT][color] = colorize(cache[NO_EFFECT][Color::WHITE], color);
- }
- if(cache[effect][color] == 0) {
- assert(cache[NO_EFFECT][color]);
- switch(effect) {
- case NO_EFFECT:
- break;
- case HORIZONTAL_FLIP:
- cache[HORIZONTAL_FLIP][color] = horz_flip(cache[NO_EFFECT][color]);
- break;
- case VERTICAL_FLIP:
- cache[VERTICAL_FLIP][color] = vert_flip(cache[NO_EFFECT][color]);
- break;
- default:
- return 0;
- }
- }
- return cache[effect][color];
- }
-}
+++ /dev/null
-// $Id: sdl_texture.hpp 4063 2006-07-21 21:05:23Z anmaster $
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#ifndef __SDL_TEXTURE_HPP__
-#define __SDL_TEXTURE_HPP__
-
-#include <config.h>
-#include <algorithm>
-
-#include <SDL.h>
-
-#include "texture.hpp"
-#include "color.hpp"
-
-namespace SDL
-{
- class Texture : public ::Texture
- {
- protected:
- SDL_Surface *texture;
- //unsigned int width;
- //unsigned int height;
-
- struct ColorCache
- {
- static const int HASHED_BITS = 3;
- static const int CACHE_SIZE = 1 << (HASHED_BITS * 3);
-
- static void ref(SDL_Surface *surface)
- {
- if(surface)
- {
- surface->refcount++;
- }
- }
-
- static int hash(const Color &color)
- {
- return
- ((int) (color.red * ((1 << HASHED_BITS) - 1)) << (HASHED_BITS - 1) * 2) |
- ((int) (color.green * ((1 << HASHED_BITS) - 1)) << (HASHED_BITS - 1)) |
- ((int) (color.blue * ((1 << HASHED_BITS) - 1)) << 0);
- }
-
- SDL_Surface *data[CACHE_SIZE];
-
- ColorCache()
- {
- memset(data, 0, CACHE_SIZE * sizeof(SDL_Surface *));
- }
-
- ~ColorCache()
- {
- std::for_each(data, data + CACHE_SIZE, SDL_FreeSurface);
- }
-
- void operator = (const ColorCache &other)
- {
- std::for_each(other.data, other.data + CACHE_SIZE, ref);
- std::for_each(data, data + CACHE_SIZE, SDL_FreeSurface);
- memcpy(data, other.data, CACHE_SIZE * sizeof(SDL_Surface *));
- }
-
- SDL_Surface *&operator [] (const Color &color)
- {
- return data[hash(color)];
- }
- };
- //typedef std::map<Color, SDL_Surface *> ColorCache;
- ColorCache cache[NUM_EFFECTS];
-
- public:
- Texture(SDL_Surface* sdlsurface);
- virtual ~Texture();
-
- SDL_Surface *get_transform(const Color &color, DrawingEffect effect);
-
- SDL_Surface *get_texture() const
- {
- return texture;
- }
-
- unsigned int get_texture_width() const
- {
- return texture->w;
- }
-
- unsigned int get_texture_height() const
- {
- return texture->h;
- }
-
- unsigned int get_image_width() const
- {
- return texture->w;
- }
-
- unsigned int get_image_height() const
- {
- return texture->h;
- }
-
- /*unsigned int get_texture_width() const
- {
- return width;
- }
-
- unsigned int get_texture_height() const
- {
- return height;
- }
-
- unsigned int get_image_width() const
- {
- return width;
- }
-
- unsigned int get_image_height() const
- {
- return height;
- }*/
- };
-}
-
-#endif
--- /dev/null
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include "video/surface.hpp"
+
+#include <config.h>
+
+#include <SDL.h>
+
+#include "video/texture.hpp"
+#include "video/video_systems.hpp"
+
+Surface::Surface(const std::string& file) :
+ texture(texture_manager->get(file)),
+ surface_data(),
+ x(0), y(0), w(0), h(0),
+ flipx(false)
+{
+ texture->ref();
+ w = texture->get_image_width();
+ h = texture->get_image_height();
+ surface_data = new_surface_data(*this);
+}
+
+Surface::Surface(const std::string& file, int x, int y, int w, int h) :
+ texture(texture_manager->get(file)),
+ surface_data(),
+ x(x), y(y), w(w), h(h),
+ flipx(false)
+{
+ texture->ref();
+ surface_data = new_surface_data(*this);
+}
+
+Surface::Surface(const Surface& other) :
+ texture(other.texture),
+ surface_data(),
+ x(other.x), y(other.y),
+ w(other.w), h(other.h),
+ flipx(false)
+{
+ texture->ref();
+ surface_data = new_surface_data(*this);
+}
+
+const Surface&
+Surface::operator= (const Surface& other)
+{
+ other.texture->ref();
+ texture->unref();
+ texture = other.texture;
+ x = other.x;
+ y = other.y;
+ w = other.w;
+ h = other.h;
+ return *this;
+}
+
+Surface::~Surface()
+{
+ free_surface_data(surface_data);
+ texture->unref();
+}
+
+/** flip the surface horizontally */
+void Surface::hflip()
+{
+ flipx = !flipx;
+}
+
+bool Surface::get_flipx() const
+{
+ return flipx;
+}
+
+Texture*
+Surface::get_texture() const
+{
+ return texture;
+}
+
+void*
+Surface::get_surface_data() const
+{
+ return surface_data;
+}
+
+int
+Surface::get_x() const
+{
+ return x;
+}
+
+int
+Surface::get_y() const
+{
+ return y;
+}
+
+int
+Surface::get_width() const
+{
+ return w;
+}
+
+int
+Surface::get_height() const
+{
+ return h;
+}
+
+Vector
+Surface::get_position() const
+{
+ return Vector(get_x(), get_y());
+}
+
+Vector
+Surface::get_size() const
+{
+ return Vector(get_width(), get_height());
+}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-#ifndef __SURFACE_HPP__
-#define __SURFACE_HPP__
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include <config.h>
+#ifndef HEADER_SUPERTUX_VIDEO_SURFACE_HPP
+#define HEADER_SUPERTUX_VIDEO_SURFACE_HPP
#include <string>
-#include <SDL.h>
+
#include "math/vector.hpp"
-#include "texture.hpp"
-#include "video_systems.hpp"
+
+class Texture;
/**
* A rectangular image.
bool flipx;
public:
- Surface(const std::string& file) :
- texture(texture_manager->get(file)),
- x(0), y(0), w(0), h(0),
- flipx(false)
- {
- texture->ref();
- w = texture->get_image_width();
- h = texture->get_image_height();
- surface_data = new_surface_data(*this);
- }
-
- Surface(const std::string& file, int x, int y, int w, int h) :
- texture(texture_manager->get(file)),
- x(x), y(y), w(w), h(h),
- flipx(false)
- {
- texture->ref();
- surface_data = new_surface_data(*this);
- }
+ Surface(const std::string& file);
+ Surface(const std::string& file, int x, int y, int w, int h);
+ Surface(const Surface& other);
+ ~Surface();
- Surface(const Surface& other) :
- texture(other.texture),
- x(other.x), y(other.y),
- w(other.w), h(other.h),
- flipx(false)
- {
- texture->ref();
- surface_data = new_surface_data(*this);
- }
-
- ~Surface()
- {
- free_surface_data(surface_data);
- texture->unref();
- }
+ const Surface& operator= (const Surface& other);
/** flip the surface horizontally */
- void hflip()
- {
- flipx = !flipx;
- }
-
- bool get_flipx() const
- {
- return flipx;
- }
-
- const Surface& operator= (const Surface& other)
- {
- other.texture->ref();
- texture->unref();
- texture = other.texture;
- x = other.x;
- y = other.y;
- w = other.w;
- h = other.h;
- return *this;
- }
-
- Texture *get_texture() const
- {
- return texture;
- }
-
- void *get_surface_data() const
- {
- return surface_data;
- }
-
- int get_x() const
- {
- return x;
- }
-
- int get_y() const
- {
- return y;
- }
-
- int get_width() const
- {
- return w;
- }
-
- int get_height() const
- {
- return h;
- }
-
- Vector get_position() const
- { return Vector(get_x(), get_y()); }
-
+ void hflip();
+ bool get_flipx() const;
+
+ Texture *get_texture() const;
+ void *get_surface_data() const;
+ int get_x() const;
+ int get_y() const;
+ int get_width() const;
+ int get_height() const;
+ Vector get_position() const;
/**
* returns a vector containing width and height
*/
- Vector get_size() const
- { return Vector(get_width(), get_height()); }
+ Vector get_size() const;
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __TEXTURE_HPP__
-#define __TEXTURE_HPP__
+#ifndef HEADER_SUPERTUX_VIDEO_TEXTURE_HPP
+#define HEADER_SUPERTUX_VIDEO_TEXTURE_HPP
#include <config.h>
#include <assert.h>
#include <string>
-#include "texture_manager.hpp"
+#include "video/texture_manager.hpp"
/// bitset for drawing effects
enum DrawingEffect {
{
texture_manager->release(this);
}
+
+private:
+ Texture(const Texture&);
+ Texture& operator=(const Texture&);
};
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "texture_manager.hpp"
+#include "video/texture_manager.hpp"
-#include <assert.h>
-#include <SDL.h>
#include <SDL_image.h>
#include <iostream>
-#include <sstream>
-#include <stdexcept>
+
#include "physfs/physfs_sdl.hpp"
-#include "video_systems.hpp"
-#include "gl_texture.hpp"
-#include "glutil.hpp"
-#include "gameconfig.hpp"
-#include "file_system.hpp"
-#include "log.hpp"
-#include "texture.hpp"
+#include "util/file_system.hpp"
+#include "util/log.hpp"
+#include "video/gl/gl_texture.hpp"
+#include "video/video_systems.hpp"
TextureManager* texture_manager = NULL;
#ifdef HAVE_OPENGL
void
-TextureManager::register_texture(GL::Texture* texture)
+TextureManager::register_texture(GLTexture* texture)
{
textures.insert(texture);
}
void
-TextureManager::remove_texture(GL::Texture* texture)
+TextureManager::remove_texture(GLTexture* texture)
{
textures.erase(texture);
}
// on error (when loading placeholder), try using empty surface
try {
- SDL_Surface* image = SDL_CreateRGBSurface(0, 1024, 1024, 8, 0, 0, 0, 0);
- if(image == 0) {
- throw err;
- }
-
- Texture* result = 0;
- try {
- result = new_texture(image);
- result->set_filename("-dummy-texture-.png");
- } catch(...) {
- delete result;
- SDL_FreeSurface(image);
- throw err;
- }
-
- SDL_FreeSurface(image);
+ SDL_Surface* image = SDL_CreateRGBSurface(0, 1024, 1024, 8, 0, 0, 0, 0);
+ if(image == 0) {
+ throw err;
+ }
+
+ Texture* result = 0;
+ try {
+ result = new_texture(image);
+ result->set_filename("-dummy-texture-.png");
+ } catch(...) {
+ delete result;
+ SDL_FreeSurface(image);
+ throw err;
+ }
+
+ SDL_FreeSurface(image);
log_warning << "Couldn't load texture '" << filename << "' (now using empty one): " << err.what() << std::endl;
- return result;
+ return result;
- // on error (when trying to use empty surface), give up
+ // on error (when trying to use empty surface), give up
} catch (const std::runtime_error& err) {
- throw err;
+ throw err;
}
}
}
}
for(ImageTextures::iterator i = image_textures.begin();
i != image_textures.end(); ++i) {
- save_texture(dynamic_cast<GL::Texture *>(i->second));
+ save_texture(dynamic_cast<GLTexture *>(i->second));
}
}
void
-TextureManager::save_texture(GL::Texture* texture)
+TextureManager::save_texture(GLTexture* texture)
{
SavedTexture saved_texture;
saved_texture.texture = texture;
saved_textures.clear();
}
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#ifndef __IMAGE_TEXTURE_MANAGER_HPP__
-#define __IMAGE_TEXTURE_MANAGER_HPP__
+#ifndef HEADER_SUPERTUX_VIDEO_TEXTURE_MANAGER_HPP
+#define HEADER_SUPERTUX_VIDEO_TEXTURE_MANAGER_HPP
#include <config.h>
-#include "glutil.hpp"
-#include <string>
-#include <vector>
#include <map>
#include <set>
+#include <string>
+#include <vector>
+
+#include "video/glutil.hpp"
class Texture;
-namespace GL { class Texture; }
+class GLTexture;
class TextureManager
{
Texture* get(const std::string& filename);
#ifdef HAVE_OPENGL
- void register_texture(GL::Texture* texture);
- void remove_texture(GL::Texture* texture);
+ void register_texture(GLTexture* texture);
+ void remove_texture(GLTexture* texture);
void save_textures();
void reload_textures();
Texture* create_image_texture(const std::string& filename);
#ifdef HAVE_OPENGL
- typedef std::set<GL::Texture*> Textures;
+ typedef std::set<GLTexture*> Textures;
Textures textures;
struct SavedTexture
{
- GL::Texture* texture;
+ GLTexture* texture;
GLint width;
GLint height;
char* pixels;
};
std::vector<SavedTexture> saved_textures;
- void save_texture(GL::Texture* texture);
+ void save_texture(GLTexture* texture);
#endif
};
extern TextureManager* texture_manager;
#endif
+
+/* EOF */
-// $Id: video_systems.cpp 5063 2007-05-27 11:32:00Z matzeb $
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
#include <config.h>
-#include "video_systems.hpp"
-#include "gameconfig.hpp"
-#include "renderer.hpp"
-#include "gl_renderer.hpp"
-#include "sdl_renderer.hpp"
-#include "lightmap.hpp"
-#include "gl_lightmap.hpp"
-#include "sdl_lightmap.hpp"
-#include "texture.hpp"
-#include "gl_texture.hpp"
-#include "sdl_texture.hpp"
-#include "gl_surface_data.hpp"
-#include "sdl_surface_data.hpp"
+#include "supertux/gameconfig.hpp"
+#include "video/gl/gl_lightmap.hpp"
+#include "video/gl/gl_renderer.hpp"
+#include "video/gl/gl_surface_data.hpp"
+#include "video/gl/gl_texture.hpp"
+#include "video/lightmap.hpp"
+#include "video/renderer.hpp"
+#include "video/sdl/sdl_lightmap.hpp"
+#include "video/sdl/sdl_renderer.hpp"
+#include "video/sdl/sdl_surface_data.hpp"
+#include "video/sdl/sdl_texture.hpp"
+#include "video/texture.hpp"
+#include "video/video_systems.hpp"
Renderer *new_renderer()
{
- switch(config->video)
+ switch(g_config->video)
{
case AUTO_VIDEO:
#ifdef HAVE_OPENGL
log_info << "new GL renderer\n";
- return new GL::Renderer();
+ return new GLRenderer();
#else
log_warning << "new SDL renderer\n";
- return new SDL::Renderer();
+ return new SDLRenderer();
#endif
#ifdef HAVE_OPENGL
case OPENGL:
log_info << "new GL renderer\n";
- return new GL::Renderer();
+ return new GLRenderer();
#endif
case PURE_SDL:
log_warning << "new SDL renderer\n";
- return new SDL::Renderer();
+ return new SDLRenderer();
default:
assert(0 && "invalid video system in config");
#ifdef HAVE_OPENGL
log_info << "new GL renderer\n";
- return new GL::Renderer();
+ return new GLRenderer();
#else
log_warning << "new SDL renderer\n";
- return new SDL::Renderer();
+ return new SDLRenderer();
#endif
}
}
Lightmap *new_lightmap()
{
- switch(config->video)
+ switch(g_config->video)
{
case AUTO_VIDEO:
#ifdef HAVE_OPENGL
- return new GL::Lightmap();
+ return new GLLightmap();
#else
- return new SDL::Lightmap();
+ return new SDLLightmap();
#endif
#ifdef HAVE_OPENGL
case OPENGL:
- return new GL::Lightmap();
+ return new GLLightmap();
#endif
case PURE_SDL:
- return new SDL::Lightmap();
+ return new SDLLightmap();
default:
assert(0 && "invalid video system in config");
#ifdef HAVE_OPENGL
- return new GL::Lightmap();
+ return new GLLightmap();
#else
- return new SDL::Lightmap();
+ return new SDLLightmap();
#endif
}
}
Texture *new_texture(SDL_Surface *image)
{
- switch(config->video)
+ switch(g_config->video)
{
case AUTO_VIDEO:
#ifdef HAVE_OPENGL
- return new GL::Texture(image);
+ return new GLTexture(image);
#else
- return new SDL::Texture(image);
+ return new SDLTexture(image);
#endif
#ifdef HAVE_OPENGL
case OPENGL:
- return new GL::Texture(image);
+ return new GLTexture(image);
#endif
case PURE_SDL:
- return new SDL::Texture(image);
+ return new SDLTexture(image);
default:
assert(0 && "invalid video system in config");
#ifdef HAVE_OPENGL
- return new GL::Texture(image);
+ return new GLTexture(image);
#else
- return new SDL::Texture(image);
+ return new SDLTexture(image);
#endif
}
}
void *new_surface_data(const Surface &surface)
{
- switch(config->video)
+ switch(g_config->video)
{
case AUTO_VIDEO:
#ifdef HAVE_OPENGL
- return new GL::SurfaceData(surface);
+ return new GLSurfaceData(surface);
#else
- return new SDL::SurfaceData(surface);
+ return new SDLSurfaceData(surface);
#endif
#ifdef HAVE_OPENGL
case OPENGL:
- return new GL::SurfaceData(surface);
+ return new GLSurfaceData(surface);
#endif
case PURE_SDL:
- return new SDL::SurfaceData(surface);
+ return new SDLSurfaceData(surface);
default:
assert(0 && "invalid video system in config");
#ifdef HAVE_OPENGL
- return new GL::SurfaceData(surface);
+ return new GLSurfaceData(surface);
#else
- return new SDL::SurfaceData(surface);
+ return new SDLSurfaceData(surface);
#endif
}
}
return "auto";
}
}
+
+/* EOF */
-// $Id: video_systems.hpp 5138 2007-08-15 01:02:22Z tuxdev $
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-#ifndef __RENDER_SYTSTEMS_HPP__
-#define __RENDER_SYTSTEMS_HPP__
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_VIDEO_VIDEO_SYSTEMS_HPP
+#define HEADER_SUPERTUX_VIDEO_VIDEO_SYSTEMS_HPP
#include <config.h>
-#include <string>
#include <SDL.h>
+#include <string>
class Renderer;
class Lightmap;
NUM_SYSTEMS
};
-Renderer *new_renderer();
-Lightmap *new_lightmap();
-Texture *new_texture(SDL_Surface *image);
-void *new_surface_data(const Surface &surface);
-void free_surface_data(void *surface_data);
+Renderer* new_renderer();
+Lightmap* new_lightmap();
+Texture* new_texture(SDL_Surface *image);
+void* new_surface_data(const Surface &surface);
+void free_surface_data(void *surface_data);
VideoSystem get_video_system(const std::string &video);
std::string get_video_string(VideoSystem video);
#endif
+
+/* EOF */
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA
-// 02111-1307, USA.
-#include <config.h>
-
-#include <stddef.h>
-#include <physfs.h>
-#include <stdexcept>
-
-#include "world.hpp"
-#include "file_system.hpp"
-#include "lisp/parser.hpp"
-#include "lisp/lisp.hpp"
-#include "physfs/physfs_stream.hpp"
-#include "scripting/squirrel_util.hpp"
-#include "scripting/serialize.hpp"
-#include "log.hpp"
-#include "worldmap/worldmap.hpp"
-#include "mainloop.hpp"
-#include "player_status.hpp"
-
-static bool has_suffix(const std::string& data, const std::string& suffix)
-{
- if (data.length() >= suffix.length())
- return data.compare(data.length() - suffix.length(), suffix.length(), suffix) == 0;
- else
- return false;
-}
-
-World* World::current_ = NULL;
-
-World::World()
-{
- is_levelset = true;
- hide_from_contribs = false;
- sq_resetobject(&world_thread);
-}
-
-World::~World()
-{
- sq_release(Scripting::global_vm, &world_thread);
- if(current_ == this)
- current_ = NULL;
-}
-
-void
-World::set_savegame_filename(const std::string& filename)
-{
- this->savegame_filename = filename;
- // make sure the savegame directory exists
- std::string dirname = FileSystem::dirname(filename);
- if(!PHYSFS_exists(dirname.c_str())) {
- if(PHYSFS_mkdir(dirname.c_str())) {
- std::ostringstream msg;
- msg << "Couldn't create directory for savegames '"
- << dirname << "': " <<PHYSFS_getLastError();
- throw std::runtime_error(msg.str());
- }
- }
-
- if(!PHYSFS_isDirectory(dirname.c_str())) {
- std::ostringstream msg;
- msg << "Savegame path '" << dirname << "' is not a directory";
- throw std::runtime_error(msg.str());
- }
-}
-
-void
-World::load(const std::string& filename)
-{
- basedir = FileSystem::dirname(filename);
-
- lisp::Parser parser;
- const lisp::Lisp* root = parser.parse(filename);
-
- const lisp::Lisp* info = root->get_lisp("supertux-world");
- if(info == NULL)
- info = root->get_lisp("supertux-level-subset");
- if(info == NULL)
- throw std::runtime_error("File is not a world or levelsubset file");
-
- hide_from_contribs = false;
- is_levelset = true;
-
- info->get("title", title);
- info->get("description", description);
- info->get("levelset", is_levelset);
- info->get("levels", levels);
- info->get("hide-from-contribs", hide_from_contribs);
-
- // Level info file doesn't define any levels, so read the
- // directory to see what we can find
-
- std::string path = basedir;
- char** files = PHYSFS_enumerateFiles(path.c_str());
- if(!files) {
- log_warning << "Couldn't read subset dir '" << path << "'" << std::endl;
- return;
- }
-
- for(const char* const* filename = files; *filename != 0; ++filename) {
- if(has_suffix(*filename, ".stl")) {
- levels.push_back(path + *filename);
- }
- }
- PHYSFS_freeList(files);
-}
-
-void
-World::run()
-{
- using namespace Scripting;
-
- current_ = this;
-
- // create new squirrel table for persistent game state
- HSQUIRRELVM vm = Scripting::global_vm;
-
- sq_pushroottable(vm);
- sq_pushstring(vm, "state", -1);
- sq_newtable(vm);
- if(SQ_FAILED(sq_createslot(vm, -3)))
- throw Scripting::SquirrelError(vm, "Couldn't create state table");
- sq_pop(vm, 1);
-
- load_state();
-
- std::string filename = basedir + "/world.nut";
- try {
- IFileStream in(filename);
-
- sq_release(global_vm, &world_thread);
- world_thread = create_thread(global_vm);
- compile_and_run(object_to_vm(world_thread), in, filename);
- } catch(std::exception& ) {
- // fallback: try to load worldmap worldmap.stwm
- using namespace WorldMapNS;
- main_loop->push_screen(new WorldMap(basedir + "worldmap.stwm"));
- }
-}
-
-void
-World::save_state()
-{
- using namespace Scripting;
-
- lisp::Writer writer(savegame_filename);
-
- writer.start_list("supertux-savegame");
- writer.write("version", 1);
-
- using namespace WorldMapNS;
- if(WorldMap::current() != NULL) {
- std::ostringstream title;
- title << WorldMap::current()->get_title();
- title << " (" << WorldMap::current()->solved_level_count()
- << "/" << WorldMap::current()->level_count() << ")";
- writer.write("title", title.str());
- }
-
- writer.start_list("tux");
- player_status->write(writer);
- writer.end_list("tux");
-
- writer.start_list("state");
-
- sq_pushroottable(global_vm);
- sq_pushstring(global_vm, "state", -1);
- if(SQ_SUCCEEDED(sq_get(global_vm, -2))) {
- Scripting::save_squirrel_table(global_vm, -1, writer);
- sq_pop(global_vm, 1);
- }
- sq_pop(global_vm, 1);
- writer.end_list("state");
-
- writer.end_list("supertux-savegame");
-}
-
-void
-World::load_state()
-{
- using namespace Scripting;
-
- try {
- lisp::Parser parser;
- const lisp::Lisp* root = parser.parse(savegame_filename);
-
- const lisp::Lisp* lisp = root->get_lisp("supertux-savegame");
- if(lisp == NULL)
- throw std::runtime_error("file is not a supertux-savegame file");
-
- int version = 1;
- lisp->get("version", version);
- if(version != 1)
- throw std::runtime_error("incompatible savegame version");
-
- const lisp::Lisp* tux = lisp->get_lisp("tux");
- if(tux == NULL)
- throw std::runtime_error("No tux section in savegame");
- player_status->read(*tux);
-
- const lisp::Lisp* state = lisp->get_lisp("state");
- if(state == NULL)
- throw std::runtime_error("No state section in savegame");
-
- sq_pushroottable(global_vm);
- sq_pushstring(global_vm, "state", -1);
- if(SQ_FAILED(sq_deleteslot(global_vm, -2, SQFalse)))
- sq_pop(global_vm, 1);
-
- sq_pushstring(global_vm, "state", -1);
- sq_newtable(global_vm);
- load_squirrel_table(global_vm, -1, state);
- if(SQ_FAILED(sq_createslot(global_vm, -3)))
- throw std::runtime_error("Couldn't create state table");
- sq_pop(global_vm, 1);
- } catch(std::exception& e) {
- log_debug << "Couldn't load savegame: " << e.what() << std::endl;
- }
-}
-
-const std::string&
-World::get_level_filename(unsigned int i) const
-{
- return levels[i];
-}
-
-unsigned int
-World::get_num_levels() const
-{
- return levels.size();
-}
-
-const std::string&
-World::get_basedir() const
-{
- return basedir;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
-//
-// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#ifndef SUPERTUX_WORLD_H
-#define SUPERTUX_WORLD_H
-
-#include <vector>
-#include <string>
-#include <squirrel.h>
-
-class World
-{
-private:
- std::vector<std::string> levels;
- std::string basedir;
- std::string savegame_filename;
- /// squirrel table that saves persistent state (about the world)
- HSQOBJECT state_table;
- HSQOBJECT world_thread;
- static World* current_;
-
-public:
- World();
- ~World();
-
- void set_savegame_filename(const std::string& filename);
- void load(const std::string& filename);
-
- void save_state();
- void load_state();
-
- const std::string& get_level_filename(unsigned int i) const;
- unsigned int get_num_levels() const;
-
- const std::string& get_basedir() const;
-
- static World* current()
- {
- return current_;
- }
-
- void run();
-
- std::string title;
- std::string description;
- bool hide_from_contribs;
- bool is_levelset;
-};
-
-#endif
-// $Id$
-//
// SuperTux - Worldmap Direction
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#ifndef __WORLDMAP_DIRECTION_HPP__
-#define __WORLDMAP_DIRECTION_HPP__
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_WORLDMAP_DIRECTION_HPP
+#define HEADER_SUPERTUX_WORLDMAP_DIRECTION_HPP
namespace WorldMapNS {
}
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.de>
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <config.h>
-#include <stddef.h>
#include <physfs.h>
-#include "worldmap/level.hpp"
-#include "sprite/sprite_manager.hpp"
+#include <stddef.h>
+
#include "sprite/sprite.hpp"
+#include "sprite/sprite_manager.hpp"
+#include "util/file_system.hpp"
+#include "util/log.hpp"
#include "video/drawing_context.hpp"
-#include "log.hpp"
-#include "file_system.hpp"
+#include "worldmap/level.hpp"
-namespace WorldMapNS
-{
+namespace WorldMapNS {
-LevelTile::LevelTile(const std::string& basedir, const lisp::Lisp* lisp)
- : solved(false), auto_play(false), basedir(basedir), picture_cached(false),
- picture(0)
+LevelTile::LevelTile(const std::string& basedir, const lisp::Lisp* lisp) :
+ solved(false),
+ auto_play(false),
+ basedir(basedir),
+ picture_cached(false),
+ picture(0)
{
lisp->get("name", name);
lisp->get("x", pos.x);
std::string spritefile = "images/worldmap/common/leveldot.sprite";
lisp->get("sprite", spritefile);
- sprite.reset(sprite_manager->create(spritefile));
+ sprite = sprite_manager->create(spritefile);
lisp->get("extro-script", extro_script);
if (!PHYSFS_exists((basedir + name).c_str()))
{
log_warning << "level file '" << name
- << "' does not exist and will not be added to the worldmap" << std::endl;
+ << "' does not exist and will not be added to the worldmap" << std::endl;
return;
}
}
}
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.de>
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#ifndef __LEVEL_TILE_HPP__
-#define __LEVEL_TILE_HPP__
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_WORLDMAP_LEVEL_HPP
+#define HEADER_SUPERTUX_WORLDMAP_LEVEL_HPP
#include <memory>
#include <string>
+
#include "math/vector.hpp"
-#include "game_object.hpp"
-#include "statistics.hpp"
+#include "supertux/game_object.hpp"
+#include "supertux/statistics.hpp"
#include "video/surface.hpp"
class Sprite;
-namespace WorldMapNS
-{
+namespace WorldMapNS {
class LevelTile : public GameObject
{
bool picture_cached;
Surface* picture;
+private:
+ LevelTile(const LevelTile&);
+ LevelTile& operator=(const LevelTile&);
};
-}
+} // namespace WorldMapNS
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux - Worldmap Spawnpoint
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <stdexcept>
-#include <iostream>
-#include "spawn_point.hpp"
-#include "lisp/lisp.hpp"
+
#include "lisp/list_iterator.hpp"
-#include "log.hpp"
+#include "util/log.hpp"
+#include "worldmap/spawn_point.hpp"
-namespace WorldMapNS
-{
+namespace WorldMapNS {
// from worldmap.cpp
Direction string_to_direction(const std::string& directory);
-SpawnPoint::SpawnPoint(const lisp::Lisp* slisp) : auto_dir(D_NONE)
+SpawnPoint::SpawnPoint(const lisp::Lisp* slisp) :
+ auto_dir(D_NONE)
{
- pos.x = -1;
- pos.y = -1;
- lisp::ListIterator iter(slisp);
- while(iter.next()) {
- const std::string& token = iter.item();
- if(token == "name") {
- iter.value()->get(name);
- } else if(token == "x") {
- iter.value()->get(pos.x);
- } else if(token == "y") {
- iter.value()->get(pos.y);
- } else if(token == "auto-dir") {
- std::string s = "";
- iter.value()->get(s);
- auto_dir = string_to_direction(s);
- } else {
- log_warning << "unknown token '" << token << "' in SpawnPoint" << std::endl;
- }
+ pos.x = -1;
+ pos.y = -1;
+ lisp::ListIterator iter(slisp);
+ while(iter.next()) {
+ const std::string& token = iter.item();
+ if(token == "name") {
+ iter.value()->get(name);
+ } else if(token == "x") {
+ iter.value()->get(pos.x);
+ } else if(token == "y") {
+ iter.value()->get(pos.y);
+ } else if(token == "auto-dir") {
+ std::string s = "";
+ iter.value()->get(s);
+ auto_dir = string_to_direction(s);
+ } else {
+ log_warning << "unknown token '" << token << "' in SpawnPoint" << std::endl;
}
+ }
- if(name == "")
- throw std::runtime_error("No name specified for spawnpoint");
- if(pos.x < 0 || pos.y < 0)
- throw std::runtime_error("Invalid coordinates for spawnpoint");
+ if(name == "")
+ throw std::runtime_error("No name specified for spawnpoint");
+ if(pos.x < 0 || pos.y < 0)
+ throw std::runtime_error("Invalid coordinates for spawnpoint");
}
}
+
+/* EOF */
-// $Id$
-//
// SuperTux - Worldmap Spawnpoint
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#ifndef __WORLDMAP_SPAWN_POINT_H__
-#define __WORLDMAP_SPAWN_POINT_H__
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_WORLDMAP_SPAWN_POINT_HPP
+#define HEADER_SUPERTUX_WORLDMAP_SPAWN_POINT_HPP
#include <string>
-#include "math/vector.hpp"
+
#include "lisp/lisp.hpp"
-#include "game_object.hpp"
+#include "math/vector.hpp"
+#include "supertux/game_object.hpp"
#include "worldmap/direction.hpp"
-namespace WorldMapNS
-{
+namespace WorldMapNS {
class SpawnPoint
{
public:
- SpawnPoint(const lisp::Lisp* lisp);
+ SpawnPoint(const lisp::Lisp* lisp);
- std::string name;
- Vector pos;
- Direction auto_dir; /**< automatically start walking in this direction */
+ std::string name;
+ Vector pos;
+ Direction auto_dir; /**< automatically start walking in this direction */
};
}
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.de>
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <config.h>
-#include "worldmap/special_tile.hpp"
-#include "sprite/sprite_manager.hpp"
#include "sprite/sprite.hpp"
+#include "sprite/sprite_manager.hpp"
#include "video/drawing_context.hpp"
+#include "worldmap/special_tile.hpp"
-namespace WorldMapNS
-{
+namespace WorldMapNS {
SpecialTile::SpecialTile(const lisp::Lisp* lisp)
: passive_message(false), invisible(false),
if(!invisible) {
std::string spritefile = "";
lisp->get("sprite", spritefile);
- sprite.reset(sprite_manager->create(spritefile));
+ sprite = sprite_manager->create(spritefile);
}
lisp->get("map-message", map_message);
}
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.de>
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#ifndef __WORLDMAP_SPECIAL_TILE_HPP__
-#define __WORLDMAP_SPECIAL_TILE_HPP__
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_WORLDMAP_SPECIAL_TILE_HPP
+#define HEADER_SUPERTUX_WORLDMAP_SPECIAL_TILE_HPP
#include <memory>
#include <string>
-#include "game_object.hpp"
-#include "math/vector.hpp"
+
#include "lisp/lisp.hpp"
+#include "math/vector.hpp"
+#include "supertux/game_object.hpp"
class Sprite;
-namespace WorldMapNS
-{
+namespace WorldMapNS {
class SpecialTile : public GameObject
{
}
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <config.h>
-#include "sprite_change.hpp"
-#include "sprite/sprite_manager.hpp"
#include "sprite/sprite.hpp"
+#include "sprite/sprite_manager.hpp"
#include "video/drawing_context.hpp"
+#include "worldmap/sprite_change.hpp"
-namespace WorldMapNS
-{
+namespace WorldMapNS {
SpriteChange::SpriteChange(const lisp::Lisp* lisp)
: change_on_touch(false), in_stay_action(false)
std::string spritefile = "";
lisp->get("sprite", spritefile);
- sprite.reset(sprite_manager->create(spritefile));
+ sprite = sprite_manager->create(spritefile);
lisp->get("stay-action", stay_action);
lisp->get("initial-stay-action", in_stay_action);
std::list<SpriteChange*> SpriteChange::all_sprite_changes;
}
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#ifndef __WORLDMAP_SPRITE_CHANGE_HPP__
-#define __WORLDMAP_SPRITE_CHANGE_HPP__
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_WORLDMAP_SPRITE_CHANGE_HPP
+#define HEADER_SUPERTUX_WORLDMAP_SPRITE_CHANGE_HPP
-#include <string>
-#include <memory>
#include <list>
-#include "game_object.hpp"
+#include <memory>
+#include <string>
+
#include "lisp/lisp.hpp"
#include "math/vector.hpp"
+#include "supertux/game_object.hpp"
class Sprite;
-namespace WorldMapNS
-{
+namespace WorldMapNS {
class SpriteChange : public GameObject
{
}
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux - Teleporter Worldmap Tile
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <config.h>
-#include "worldmap/teleporter.hpp"
-#include "sprite/sprite_manager.hpp"
#include "sprite/sprite.hpp"
+#include "sprite/sprite_manager.hpp"
#include "video/drawing_context.hpp"
+#include "worldmap/teleporter.hpp"
-namespace WorldMapNS
-{
+namespace WorldMapNS {
Teleporter::Teleporter(const lisp::Lisp* lisp)
: automatic(false)
std::string spritefile = "";
if (lisp->get("sprite", spritefile)) {
- sprite.reset(sprite_manager->create(spritefile));
+ sprite = sprite_manager->create(spritefile);
}
lisp->get("worldmap", worldmap);
}
}
+
+/* EOF */
-// $Id$
-//
// SuperTux - Teleporter Worldmap Tile
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#ifndef __WORLDMAP_TELEPORTER_HPP__
-#define __WORLDMAP_TELEPORTER_HPP__
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_WORLDMAP_TELEPORTER_HPP
+#define HEADER_SUPERTUX_WORLDMAP_TELEPORTER_HPP
#include <memory>
#include <string>
-#include "game_object.hpp"
-#include "math/vector.hpp"
+
#include "lisp/lisp.hpp"
+#include "math/vector.hpp"
+#include "supertux/game_object.hpp"
class Sprite;
-namespace WorldMapNS
-{
+namespace WorldMapNS {
class Teleporter : public GameObject
{
}
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux - A Jump'n Run
// Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.de>
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include <config.h>
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
-#include "tux.hpp"
+#include "control/joystickkeyboardcontroller.hpp"
+#include "scripting/squirrel_util.hpp"
#include "sprite/sprite.hpp"
#include "sprite/sprite_manager.hpp"
-#include "video/drawing_context.hpp"
-#include "player_status.hpp"
-#include "worldmap.hpp"
+#include "supertux/main.hpp"
+#include "supertux/player_status.hpp"
+#include "supertux/tile.hpp"
#include "worldmap/level.hpp"
-#include "special_tile.hpp"
-#include "sprite_change.hpp"
-#include "control/joystickkeyboardcontroller.hpp"
-#include "scripting/squirrel_util.hpp"
-#include "tile.hpp"
-#include "main.hpp"
+#include "worldmap/tux.hpp"
-namespace WorldMapNS
-{
+namespace WorldMapNS {
static const float TUXSPEED = 200;
static const float map_message_TIME = 2.8f;
-Tux::Tux(WorldMap* worldmap_)
- : worldmap(worldmap_)
+Tux::Tux(WorldMap* worldmap_) :
+ back_direction(),
+ worldmap(worldmap_),
+ sprite(),
+ controller(),
+ input_direction(),
+ direction(),
+ tile_pos(),
+ offset(),
+ moving(),
+ ghost_mode()
{
- sprite.reset(sprite_manager->create("images/worldmap/common/tux.sprite"));
+ sprite = sprite_manager->create("images/worldmap/common/tux.sprite");
offset = 0;
moving = false;
sprite->draw(context, get_pos(), LAYER_OBJECTS);
}
-
Vector
Tux::get_pos()
{
float y = tile_pos.y * 32;
switch(direction)
- {
+ {
case D_WEST:
x -= offset - 32;
break;
break;
case D_NONE:
break;
- }
+ }
return Vector(x, y);
}
Tux::canWalk(int tile_data, Direction dir)
{
return ghost_mode ||
- ((tile_data & Tile::WORLDMAP_NORTH && dir == D_NORTH) ||
- (tile_data & Tile::WORLDMAP_SOUTH && dir == D_SOUTH) ||
- (tile_data & Tile::WORLDMAP_EAST && dir == D_EAST) ||
- (tile_data & Tile::WORLDMAP_WEST && dir == D_WEST));
+ ((tile_data & Tile::WORLDMAP_NORTH && dir == D_NORTH) ||
+ (tile_data & Tile::WORLDMAP_SOUTH && dir == D_SOUTH) ||
+ (tile_data & Tile::WORLDMAP_EAST && dir == D_EAST) ||
+ (tile_data & Tile::WORLDMAP_WEST && dir == D_WEST));
}
void
// direction and the apply_action_ are opposites, since they "see"
// directions in a different way
if((direction == D_NORTH && special_tile->apply_action_south) ||
- (direction == D_SOUTH && special_tile->apply_action_north) ||
- (direction == D_WEST && special_tile->apply_action_east) ||
- (direction == D_EAST && special_tile->apply_action_west))
+ (direction == D_SOUTH && special_tile->apply_action_north) ||
+ (direction == D_WEST && special_tile->apply_action_east) ||
+ (direction == D_EAST && special_tile->apply_action_west))
{
if(special_tile->passive_message) {
worldmap->passive_message = special_tile->map_message;
if ((worldmap->at_level())
|| (worldmap->tile_data_at(tile_pos) & Tile::WORLDMAP_STOP)
|| (special_tile && !special_tile->passive_message
- && special_tile->script == "")
+ && special_tile->script == "")
|| (teleporter) || ghost_mode) {
if(special_tile && !special_tile->map_message.empty()
- && !special_tile->passive_message)
+ && !special_tile->passive_message)
worldmap->passive_message_timer.start(0);
stop();
return;
void
Tux::updateInputDirection()
{
- if(main_controller->hold(Controller::UP))
+ if(g_main_controller->hold(Controller::UP))
input_direction = D_NORTH;
- else if(main_controller->hold(Controller::DOWN))
+ else if(g_main_controller->hold(Controller::DOWN))
input_direction = D_SOUTH;
- else if(main_controller->hold(Controller::LEFT))
+ else if(g_main_controller->hold(Controller::LEFT))
input_direction = D_WEST;
- else if(main_controller->hold(Controller::RIGHT))
+ else if(g_main_controller->hold(Controller::RIGHT))
input_direction = D_EAST;
}
}
}
-}
+} // namespace WorldmapNS
+
+/* EOF */
-// $Id$
-//
// SuperTux - A Jump'n Run
// Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.de>
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#ifndef __WORLDMAP_TUX_HPP__
-#define __WORLDMAP_TUX_HPP__
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_WORLDMAP_TUX_HPP
+#define HEADER_SUPERTUX_WORLDMAP_TUX_HPP
-#include <memory>
-#include "game_object.hpp"
-#include "worldmap.hpp"
+#include "worldmap/worldmap.hpp"
class Sprite;
-namespace WorldMapNS
-{
+namespace WorldMapNS {
class WorldMap;
bool ghost_mode;
+private:
void stop();
-
bool canWalk(int tile_data, Direction dir); /**< check if we can leave a tile (with given "tile_data") in direction "dir" */
void updateInputDirection(); /**< if controller was pressed, update input_direction */
void tryStartWalking(); /**< try starting to walk in input_direction */
Vector get_pos();
Vector get_tile_pos() const { return tile_pos; }
void set_tile_pos(Vector p) { tile_pos = p; }
+
+private:
+ Tux(const Tux&);
+ Tux& operator=(const Tux&);
};
-}
+} // namespace WorldMapNS
#endif
+
+/* EOF */
-// $Id$
-//
// SuperTux - A Jump'n Run
// Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.de>
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#include "worldmap/worldmap.hpp"
+
#include <config.h>
-#include <iostream>
-#include <fstream>
-#include <vector>
#include <cassert>
-#include <stdexcept>
+#include <fstream>
+#include <iostream>
+#include <physfs.h>
#include <sstream>
+#include <stdexcept>
#include <unistd.h>
-#include <physfs.h>
-
-#include "worldmap.hpp"
+#include <vector>
-#include "gettext.hpp"
-#include "log.hpp"
-#include "mainloop.hpp"
-#include "shrinkfade.hpp"
-#include "video/surface.hpp"
-#include "video/drawing_context.hpp"
-#include "sprite/sprite.hpp"
-#include "sprite/sprite_manager.hpp"
#include "audio/sound_manager.hpp"
-#include "lisp/parser.hpp"
-#include "lisp/lisp.hpp"
-#include "lisp/list_iterator.hpp"
-#include "lisp/writer.hpp"
-#include "game_session.hpp"
-#include "sector.hpp"
-#include "worldmap.hpp"
-#include "resources.hpp"
-#include "log.hpp"
-#include "world.hpp"
-#include "player_status.hpp"
-#include "textscroller.hpp"
-#include "main.hpp"
-#include "spawn_point.hpp"
-#include "file_system.hpp"
-#include "physfs/physfs_stream.hpp"
-#include "tile_manager.hpp"
-#include "tile_set.hpp"
+#include "control/joystickkeyboardcontroller.hpp"
#include "gui/menu.hpp"
#include "gui/mousecursor.hpp"
-#include "control/joystickkeyboardcontroller.hpp"
+#include "lisp/lisp.hpp"
+#include "lisp/list_iterator.hpp"
+#include "lisp/parser.hpp"
#include "object/background.hpp"
#include "object/tilemap.hpp"
-#include "options_menu.hpp"
+#include "physfs/physfs_stream.hpp"
#include "scripting/squirrel_error.hpp"
#include "scripting/squirrel_util.hpp"
+#include "sprite/sprite.hpp"
+#include "sprite/sprite_manager.hpp"
+#include "supertux/game_session.hpp"
+#include "supertux/main.hpp"
+#include "supertux/mainloop.hpp"
+#include "supertux/options_menu.hpp"
+#include "supertux/player_status.hpp"
+#include "supertux/resources.hpp"
+#include "supertux/sector.hpp"
+#include "supertux/shrinkfade.hpp"
+#include "supertux/spawn_point.hpp"
+#include "supertux/textscroller.hpp"
+#include "supertux/tile_manager.hpp"
+#include "supertux/tile_set.hpp"
+#include "supertux/world.hpp"
+#include "util/file_system.hpp"
+#include "util/gettext.hpp"
+#include "util/log.hpp"
+#include "util/log.hpp"
+#include "video/drawing_context.hpp"
+#include "video/surface.hpp"
#include "worldmap/level.hpp"
#include "worldmap/special_tile.hpp"
-#include "worldmap/tux.hpp"
#include "worldmap/sprite_change.hpp"
+#include "worldmap/tux.hpp"
+#include "worldmap/worldmap.hpp"
static const float CAMERA_PAN_SPEED = 5.0;
Direction reverse_dir(Direction direction)
{
switch(direction)
- {
+ {
case D_WEST:
return D_EAST;
case D_EAST:
return D_NORTH;
case D_NONE:
return D_NONE;
- }
+ }
return D_NONE;
}
direction_to_string(Direction direction)
{
switch(direction)
- {
+ {
case D_WEST:
return "west";
case D_EAST:
return "south";
default:
return "none";
- }
+ }
}
Direction
//---------------------------------------------------------------------------
-WorldMap::WorldMap(const std::string& filename, const std::string& force_spawnpoint)
- : tux(0), tileset(NULL), free_tileset(false),
- ambient_light( 1.0f, 1.0f, 1.0f, 1.0f ), force_spawnpoint(force_spawnpoint),
- in_level(false), panning(false)
+WorldMap::WorldMap(const std::string& filename, const std::string& force_spawnpoint) :
+ tux(0),
+ tileset(NULL),
+ free_tileset(false),
+ ambient_light( 1.0f, 1.0f, 1.0f, 1.0f ),
+ force_spawnpoint(force_spawnpoint),
+ in_level(false),
+ panning(false)
{
tux = new Tux(this);
add_object(tux);
void
WorldMap::change(const std::string& filename, const std::string& force_spawnpoint)
{
- main_loop->exit_screen();
- main_loop->push_screen(new WorldMap(filename, force_spawnpoint));
+ g_main_loop->exit_screen();
+ g_main_loop->push_screen(new WorldMap(filename, force_spawnpoint));
}
void
if (!(new_pos->x >= 0 && new_pos->x < get_width()
&& new_pos->y >= 0 && new_pos->y < get_height()))
- { // New position is outsite the tilemap
- return false;
- }
+ { // New position is outsite the tilemap
+ return false;
+ }
else
- { // Check if the tile allows us to go to new_pos
- int old_tile_data = tile_data_at(old_pos);
- int new_tile_data = tile_data_at(*new_pos);
- switch(direction)
- {
- case D_WEST:
- return (old_tile_data & Tile::WORLDMAP_WEST
- && new_tile_data & Tile::WORLDMAP_EAST);
+ { // Check if the tile allows us to go to new_pos
+ int old_tile_data = tile_data_at(old_pos);
+ int new_tile_data = tile_data_at(*new_pos);
+ switch(direction)
+ {
+ case D_WEST:
+ return (old_tile_data & Tile::WORLDMAP_WEST
+ && new_tile_data & Tile::WORLDMAP_EAST);
- case D_EAST:
- return (old_tile_data & Tile::WORLDMAP_EAST
- && new_tile_data & Tile::WORLDMAP_WEST);
+ case D_EAST:
+ return (old_tile_data & Tile::WORLDMAP_EAST
+ && new_tile_data & Tile::WORLDMAP_WEST);
- case D_NORTH:
- return (old_tile_data & Tile::WORLDMAP_NORTH
- && new_tile_data & Tile::WORLDMAP_SOUTH);
+ case D_NORTH:
+ return (old_tile_data & Tile::WORLDMAP_NORTH
+ && new_tile_data & Tile::WORLDMAP_SOUTH);
- case D_SOUTH:
- return (old_tile_data & Tile::WORLDMAP_SOUTH
- && new_tile_data & Tile::WORLDMAP_NORTH);
+ case D_SOUTH:
+ return (old_tile_data & Tile::WORLDMAP_SOUTH
+ && new_tile_data & Tile::WORLDMAP_NORTH);
- case D_NONE:
- assert(!"path_ok() can't walk if direction is NONE");
- }
- return false;
+ case D_NONE:
+ assert(!"path_ok() can't walk if direction is NONE");
}
+ return false;
+ }
}
void
int dirdata = available_directions_at(tux->get_tile_pos());
// first, test for crossroads
if (dirdata == Tile::WORLDMAP_CNSE ||
- dirdata == Tile::WORLDMAP_CNSW ||
- dirdata == Tile::WORLDMAP_CNEW ||
- dirdata == Tile::WORLDMAP_CSEW ||
- dirdata == Tile::WORLDMAP_CNSEW)
+ dirdata == Tile::WORLDMAP_CNSW ||
+ dirdata == Tile::WORLDMAP_CNEW ||
+ dirdata == Tile::WORLDMAP_CSEW ||
+ dirdata == Tile::WORLDMAP_CNSEW)
dir = D_NONE;
else if (dirdata & Tile::WORLDMAP_NORTH
- && tux->back_direction != D_NORTH)
+ && tux->back_direction != D_NORTH)
dir = D_NORTH;
else if (dirdata & Tile::WORLDMAP_SOUTH
- && tux->back_direction != D_SOUTH)
+ && tux->back_direction != D_SOUTH)
dir = D_SOUTH;
else if (dirdata & Tile::WORLDMAP_EAST
- && tux->back_direction != D_EAST)
+ && tux->back_direction != D_EAST)
dir = D_EAST;
else if (dirdata & Tile::WORLDMAP_WEST
- && tux->back_direction != D_WEST)
+ && tux->back_direction != D_WEST)
dir = D_WEST;
if (dir != D_NONE) {
Menu::set_current(0);
break;
case MNID_QUITWORLDMAP: // Quit Worldmap
- main_loop->exit_screen();
+ g_main_loop->exit_screen();
break;
}
}
for(size_t i = 0; i < game_objects.size(); ++i) {
GameObject* object = game_objects[i];
if(!panning || object != tux) {
- object->update(delta);
+ object->update(delta);
}
}
clamp_camera_position(camera_offset);
if(panning) {
- if(requested_pos.x != camera_offset.x) {
- pan_pos.x = camera_offset.x;
- }
- if(requested_pos.y != camera_offset.y) {
- pan_pos.y = camera_offset.y;
- }
+ if(requested_pos.x != camera_offset.x) {
+ pan_pos.x = camera_offset.x;
+ }
+ if(requested_pos.y != camera_offset.y) {
+ pan_pos.y = camera_offset.y;
+ }
}
// handle input
bool enter_level = false;
- if(main_controller->pressed(Controller::ACTION)
- || main_controller->pressed(Controller::JUMP)
- || main_controller->pressed(Controller::MENU_SELECT)) {
+ if(g_main_controller->pressed(Controller::ACTION)
+ || g_main_controller->pressed(Controller::JUMP)
+ || g_main_controller->pressed(Controller::MENU_SELECT)) {
/* some people define UP and JUMP on the same key... */
- if(!main_controller->pressed(Controller::UP))
+ if(!g_main_controller->pressed(Controller::UP))
enter_level = true;
}
- if(main_controller->pressed(Controller::PAUSE_MENU))
+ if(g_main_controller->pressed(Controller::PAUSE_MENU))
on_escape_press();
// check for teleporters
}
if (enter_level && !tux->is_moving())
- {
- /* Check level action */
- LevelTile* level = at_level();
- if (!level) {
- //Respawn if player on a tile with no level and nowhere to go.
- int tile_data = tile_data_at(tux->get_tile_pos());
- if(!( tile_data & ( Tile::WORLDMAP_NORTH | Tile::WORLDMAP_SOUTH | Tile::WORLDMAP_WEST | Tile::WORLDMAP_EAST ))){
- log_warning << "Player at illegal position " << tux->get_tile_pos().x << ", " << tux->get_tile_pos().y << " respawning." << std::endl;
- move_to_spawnpoint("main");
- return;
- }
- log_warning << "No level to enter at: " << tux->get_tile_pos().x << ", " << tux->get_tile_pos().y << std::endl;
+ {
+ /* Check level action */
+ LevelTile* level = at_level();
+ if (!level) {
+ //Respawn if player on a tile with no level and nowhere to go.
+ int tile_data = tile_data_at(tux->get_tile_pos());
+ if(!( tile_data & ( Tile::WORLDMAP_NORTH | Tile::WORLDMAP_SOUTH | Tile::WORLDMAP_WEST | Tile::WORLDMAP_EAST ))){
+ log_warning << "Player at illegal position " << tux->get_tile_pos().x << ", " << tux->get_tile_pos().y << " respawning." << std::endl;
+ move_to_spawnpoint("main");
return;
}
+ log_warning << "No level to enter at: " << tux->get_tile_pos().x << ", " << tux->get_tile_pos().y << std::endl;
+ return;
+ }
- if (level->pos == tux->get_tile_pos()) {
- try {
- Vector shrinkpos = Vector(level->pos.x*32 + 16 - camera_offset.x,
- level->pos.y*32 + 8 - camera_offset.y);
- std::string levelfile = levels_path + level->get_name();
+ if (level->pos == tux->get_tile_pos()) {
+ try {
+ Vector shrinkpos = Vector(level->pos.x*32 + 16 - camera_offset.x,
+ level->pos.y*32 + 8 - camera_offset.y);
+ std::string levelfile = levels_path + level->get_name();
- // update state and savegame
- save_state();
+ // update state and savegame
+ save_state();
- main_loop->push_screen(new GameSession(levelfile, &level->statistics),
+ g_main_loop->push_screen(new GameSession(levelfile, &level->statistics),
new ShrinkFade(shrinkpos, 1.0f));
- in_level = true;
- } catch(std::exception& e) {
- log_fatal << "Couldn't load level: " << e.what() << std::endl;
- }
+ in_level = true;
+ } catch(std::exception& e) {
+ log_fatal << "Couldn't load level: " << e.what() << std::endl;
}
}
+ }
else
- {
- // tux->set_direction(input_direction);
- }
+ {
+ // tux->set_direction(input_direction);
+ }
}
}
{
if (int(get_width()*32) < SCREEN_WIDTH || int(get_height()*32) < SCREEN_HEIGHT)
context.draw_filled_rect(Vector(0, 0), Vector(SCREEN_WIDTH, SCREEN_HEIGHT),
- Color(0.0f, 0.0f, 0.0f, 1.0f), LAYER_BACKGROUND0);
+ Color(0.0f, 0.0f, 0.0f, 1.0f), LAYER_BACKGROUND0);
context.set_ambient_color( ambient_light );
context.push_transform();
}
}
-/*
+ /*
// FIXME: make this a runtime switch similar to draw_collrects/show_collrects?
// draw visual indication of possible walk directions
static int flipme = 0;
if (flipme++ & 0x04)
for (int x = 0; x < get_width(); x++) {
- for (int y = 0; y < get_height(); y++) {
- int data = tile_data_at(Vector(x,y));
- int px = x * 32;
- int py = y * 32;
- const int W = 4;
- if (data & Tile::WORLDMAP_NORTH) context.draw_filled_rect(Rect(px + 16-W, py , px + 16+W, py + 16-W), Color(0.2f, 0.2f, 0.2f, 0.7f), LAYER_FOREGROUND1 + 1000);
- if (data & Tile::WORLDMAP_SOUTH) context.draw_filled_rect(Rect(px + 16-W, py + 16+W, px + 16+W, py + 32 ), Color(0.2f, 0.2f, 0.2f, 0.7f), LAYER_FOREGROUND1 + 1000);
- if (data & Tile::WORLDMAP_EAST) context.draw_filled_rect(Rect(px + 16+W, py + 16-W, px + 32 , py + 16+W), Color(0.2f, 0.2f, 0.2f, 0.7f), LAYER_FOREGROUND1 + 1000);
- if (data & Tile::WORLDMAP_WEST) context.draw_filled_rect(Rect(px , py + 16-W, px + 16-W, py + 16+W), Color(0.2f, 0.2f, 0.2f, 0.7f), LAYER_FOREGROUND1 + 1000);
- if (data & Tile::WORLDMAP_DIR_MASK) context.draw_filled_rect(Rect(px + 16-W, py + 16-W, px + 16+W, py + 16+W), Color(0.2f, 0.2f, 0.2f, 0.7f), LAYER_FOREGROUND1 + 1000);
- if (data & Tile::WORLDMAP_STOP) context.draw_filled_rect(Rect(px + 4 , py + 4 , px + 28 , py + 28 ), Color(0.2f, 0.2f, 0.2f, 0.7f), LAYER_FOREGROUND1 + 1000);
- }
+ for (int y = 0; y < get_height(); y++) {
+ int data = tile_data_at(Vector(x,y));
+ int px = x * 32;
+ int py = y * 32;
+ const int W = 4;
+ if (data & Tile::WORLDMAP_NORTH) context.draw_filled_rect(Rect(px + 16-W, py , px + 16+W, py + 16-W), Color(0.2f, 0.2f, 0.2f, 0.7f), LAYER_FOREGROUND1 + 1000);
+ if (data & Tile::WORLDMAP_SOUTH) context.draw_filled_rect(Rect(px + 16-W, py + 16+W, px + 16+W, py + 32 ), Color(0.2f, 0.2f, 0.2f, 0.7f), LAYER_FOREGROUND1 + 1000);
+ if (data & Tile::WORLDMAP_EAST) context.draw_filled_rect(Rect(px + 16+W, py + 16-W, px + 32 , py + 16+W), Color(0.2f, 0.2f, 0.2f, 0.7f), LAYER_FOREGROUND1 + 1000);
+ if (data & Tile::WORLDMAP_WEST) context.draw_filled_rect(Rect(px , py + 16-W, px + 16-W, py + 16+W), Color(0.2f, 0.2f, 0.2f, 0.7f), LAYER_FOREGROUND1 + 1000);
+ if (data & Tile::WORLDMAP_DIR_MASK) context.draw_filled_rect(Rect(px + 16-W, py + 16-W, px + 16+W, py + 16+W), Color(0.2f, 0.2f, 0.2f, 0.7f), LAYER_FOREGROUND1 + 1000);
+ if (data & Tile::WORLDMAP_STOP) context.draw_filled_rect(Rect(px + 4 , py + 4 , px + 28 , py + 28 ), Color(0.2f, 0.2f, 0.2f, 0.7f), LAYER_FOREGROUND1 + 1000);
+ }
}
-*/
+ */
draw_status(context);
context.pop_transform();
// if level is solved, draw level picture behind stats
/*
- if (level->solved) {
+ if (level->solved) {
if (const Surface* picture = level->get_picture()) {
- Vector pos = Vector(SCREEN_WIDTH - picture->get_width(), SCREEN_HEIGHT - picture->get_height());
- context.push_transform();
- context.set_alpha(0.5);
- context.draw_surface(picture, pos, LAYER_FOREGROUND1-1);
- context.pop_transform();
+ Vector pos = Vector(SCREEN_WIDTH - picture->get_width(), SCREEN_HEIGHT - picture->get_height());
+ context.push_transform();
+ context.set_alpha(0.5);
+ context.draw_surface(picture, pos, LAYER_FOREGROUND1-1);
+ context.pop_transform();
+ }
}
- }
*/
level->statistics.draw_worldmap_info(context);
/* Display an in-map message in the map, if any as been selected */
if(!special_tile->map_message.empty() && !special_tile->passive_message)
context.draw_text(normal_font, special_tile->map_message,
- Vector(SCREEN_WIDTH/2,
- SCREEN_HEIGHT - normal_font->get_height() - 60),
- ALIGN_CENTER, LAYER_FOREGROUND1, WorldMap::message_color);
+ Vector(SCREEN_WIDTH/2,
+ SCREEN_HEIGHT - normal_font->get_height() - 60),
+ ALIGN_CENTER, LAYER_FOREGROUND1, WorldMap::message_color);
break;
}
}
/* Display a passive message in the map, if needed */
if(passive_message_timer.started())
context.draw_text(normal_font, passive_message,
- Vector(SCREEN_WIDTH/2, SCREEN_HEIGHT - normal_font->get_height() - 60),
- ALIGN_CENTER, LAYER_FOREGROUND1, WorldMap::message_color);
+ Vector(SCREEN_WIDTH/2, SCREEN_HEIGHT - normal_font->get_height() - 60),
+ ALIGN_CENTER, LAYER_FOREGROUND1, WorldMap::message_color);
context.pop_transform();
}
// doesn't exist or erroneous; do nothing
}
-
if(init_script != "") {
std::istringstream in(init_script);
run_script(in, "WorldMap::init");
sq_pushstring(vm, level->get_name().c_str(), -1);
sq_newtable(vm);
- store_bool(vm, "solved", level->solved);
+ store_bool(vm, "solved", level->solved);
level->statistics.serialize_to_squirrel(vm);
sq_createslot(vm, -3);
}
} // namespace WorldMapNS
+
+/* EOF */
-// $Id$
-//
// SuperTux
// Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.de>
// Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
//
-// 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 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 3 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
// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#ifndef SUPERTUX_WORLDMAP_H
-#define SUPERTUX_WORLDMAP_H
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef HEADER_SUPERTUX_WORLDMAP_WORLDMAP_HPP
+#define HEADER_SUPERTUX_WORLDMAP_WORLDMAP_HPP
-#include <vector>
#include <string>
+#include <vector>
-#include "math/vector.hpp"
-#include "lisp/lisp.hpp"
#include "control/controller.hpp"
-#include "statistics.hpp"
-#include "timer.hpp"
-#include "screen.hpp"
-#include "tile_manager.hpp"
-#include "game_object.hpp"
-#include "console.hpp"
-#include "../level.hpp"
+#include "lisp/lisp.hpp"
+#include "math/vector.hpp"
+#include "supertux/console.hpp"
+#include "supertux/game_object.hpp"
+#include "supertux/level.hpp"
+#include "supertux/screen.hpp"
+#include "supertux/statistics.hpp"
+#include "supertux/tile_manager.hpp"
+#include "supertux/timer.hpp"
+#include "worldmap/direction.hpp"
+#include "worldmap/spawn_point.hpp"
#include "worldmap/special_tile.hpp"
#include "worldmap/sprite_change.hpp"
#include "worldmap/teleporter.hpp"
-#include "worldmap/spawn_point.hpp"
-#include "worldmap/direction.hpp"
class Sprite;
class Menu;
Vector get_camera_pos_for_tux();
void clamp_camera_position(Vector& c);
+
+private:
+ WorldMap(const WorldMap&);
+ WorldMap& operator=(const WorldMap&);
};
} // namespace WorldMapNS
#endif
+
+/* EOF */
--- /dev/null
+// SuperTux
+// Copyright (C) 2009 Ingo Ruhnke <grumbel@gmx.de>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+#include <iostream>
+#include <errno.h>
+#include <string.h>
+
+#include "addon/md5.hpp"
+
+int main(int argc, char** argv)
+{
+ for(int i = 1; i < argc; ++i)
+ {
+ std::ifstream in(argv[i], std::ios::binary);
+ if (!in)
+ {
+ std::cerr << argv[0] << ": " << argv[i] << ": " << strerror(errno) << std::endl;
+ }
+ else
+ {
+ MD5 md5(in);
+ std::cout << md5.hex_digest() << " " << argv[i] << std::endl;
+ }
+ }
+ return 0;
+}
+
+/* EOF */
#include "create_wrapper.hpp"
#include "globals.hpp"
-#include <stdio.h>
#include <iostream>
#include <sstream>
#include <stdexcept>
+#include <stdio.h>
void
WrapperCreator::create_wrapper(Namespace* ns)
<< " * '" << fromfile << "'\n"
<< " * DO NOT CHANGE\n"
<< " */\n"
- << "#ifndef __" << modulename << "_WRAPPER_H__\n"
- << "#define __" << modulename << "_WRAPPER_H__\n"
- << "\n"
- << "#include <squirrel.h>\n"
+ << "#ifndef HEADER_SUPERTUX_SCRIPTING_WRAPPER_HPP\n" //TODO avoid hardcoding
+ << "#define HEADER_SUPERTUX_SCRIPTING_WRAPPER_HPP\n"
<< "\n"
- << "namespace Scripting\n"
- << "{\n"
+ << "namespace Scripting {\n"
<< "\n";
hppout << "void register_" << modulename << "_wrapper(HSQUIRRELVM v);\n"
hppout <<"\n"
<< "}\n"
<< "\n"
- << "#endif\n";
+ << "#endif\n"
+ << "\n"
+ << "/* EOF */\n";
// cpp header
out << "/**\n"
<< " * '" << fromfile << "'\n"
<< " * DO NOT CHANGE\n"
<< " */\n"
- << "#include <config.h>\n"
<< "\n"
- << "#include <new>\n"
- << "#include <assert.h>\n"
- << "#include <string>\n"
<< "#include <sstream>\n"
- << "#include <squirrel.h>\n"
- << "#include \"squirrel_error.hpp\"\n"
- << "#include \"wrapper.interface.hpp\"\n"
<< "\n"
- << "namespace Scripting\n"
- << "{\n"
- << "namespace Wrapper\n"
- << "{\n"
+ << "#include \"scripting/squirrel_error.hpp\"\n"
+ << "#include \"scripting/wrapper.interface.hpp\"\n"
+ << "\n"
+ << "namespace Scripting {\n"
+ << "namespace Wrapper {\n"
<< "\n";
for(std::vector<AtomicType*>::iterator i = ns->types.begin();
out << "}\n"
<< "\n"
- << "} // end of namespace Scripting\n";
+ << "} // end of namespace Scripting\n"
+ << "\n"
+ << "/* EOF */\n";
}
void