summaryrefslogtreecommitdiff
path: root/packages/sdl
diff options
context:
space:
mode:
authormarco <marco@3ad0048d-3df7-0310-abae-a5850022a9f2>2008-01-27 10:35:18 +0000
committermarco <marco@3ad0048d-3df7-0310-abae-a5850022a9f2>2008-01-27 10:35:18 +0000
commitc1de70bf2792e10edd0992380dc3a0243c52c7c9 (patch)
treec4a3c0c1dc6afee35a5dd536c0c00371401ed049 /packages/sdl
parentbb8ca14d09ca9536577ebe2ed1d09a62261d4d4c (diff)
downloadfpc-c1de70bf2792e10edd0992380dc3a0243c52c7c9.tar.gz
* sdl moved
git-svn-id: http://svn.freepascal.org/svn/fpc/trunk@10024 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'packages/sdl')
-rw-r--r--packages/sdl/LGPL504
-rw-r--r--packages/sdl/LGPL.addon25
-rw-r--r--packages/sdl/MPL-1.1470
-rw-r--r--packages/sdl/Makefile2444
-rw-r--r--packages/sdl/Makefile.fpc33
-rw-r--r--packages/sdl/README7
-rw-r--r--packages/sdl/fpmake.pp91
-rw-r--r--packages/sdl/src/jedi-sdl.inc438
-rw-r--r--packages/sdl/src/libxmlparser.pas2688
-rw-r--r--packages/sdl/src/logger.pas189
-rw-r--r--packages/sdl/src/powersdl.inc176
-rw-r--r--packages/sdl/src/sdl.pas4288
-rw-r--r--packages/sdl/src/sdl_gfx.pas691
-rw-r--r--packages/sdl/src/sdl_image.pas345
-rw-r--r--packages/sdl/src/sdl_mixer.pas1122
-rw-r--r--packages/sdl/src/sdl_mixer_nosmpeg.pas967
-rw-r--r--packages/sdl/src/sdl_net.pas629
-rw-r--r--packages/sdl/src/sdl_ttf.pas501
-rw-r--r--packages/sdl/src/sdlutils.pas4363
-rw-r--r--packages/sdl/src/smpeg.pas435
20 files changed, 20406 insertions, 0 deletions
diff --git a/packages/sdl/LGPL b/packages/sdl/LGPL
new file mode 100644
index 0000000000..b1e3f5a263
--- /dev/null
+++ b/packages/sdl/LGPL
@@ -0,0 +1,504 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+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 and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, 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 library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete 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 distribute a copy of this License along with the
+Library.
+
+ 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 Library or any portion
+of it, thus forming a work based on the Library, 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) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+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 Library, 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 Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you 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.
+
+ If distribution of 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 satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be 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.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library 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.
+
+ 9. 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 Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+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 with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library 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 Library.
+
+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.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library 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.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser 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 Library
+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 Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+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
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "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
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. 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 LIBRARY 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
+LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/packages/sdl/LGPL.addon b/packages/sdl/LGPL.addon
new file mode 100644
index 0000000000..12154ea98b
--- /dev/null
+++ b/packages/sdl/LGPL.addon
@@ -0,0 +1,25 @@
+This is the file LICENSE.addon, it applies to the SDL header translation
+distributed as part of packages/extra of Free Pascal.
+
+The source code of the JEDI-SDL header translations and packages are
+distributed under the Library GNU General Public License
+(see the file LICENSE) with the following modification:
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent modules,
+and to copy and distribute the resulting executable under terms of your choice,
+provided that you also meet, for each linked independent module, the terms
+and conditions of the license of that module. An independent module is a module
+which is not derived from or based on this library. If you modify this
+library, you may extend this exception to your version of the library, but you are
+not obligated to do so. If you do not wish to do so, delete this exception
+statement from your version.
+
+If you didn't receive a copy of the file COPYING, contact:
+ Free Software Foundation
+ 675 Mass Ave
+ Cambridge, MA 02139
+ USA
+
+This change in licensing (original JEDI-SDL is MPL) is done with permission.
diff --git a/packages/sdl/MPL-1.1 b/packages/sdl/MPL-1.1
new file mode 100644
index 0000000000..7714141d15
--- /dev/null
+++ b/packages/sdl/MPL-1.1
@@ -0,0 +1,470 @@
+ MOZILLA PUBLIC LICENSE
+ Version 1.1
+
+ ---------------
+
+1. Definitions.
+
+ 1.0.1. "Commercial Use" means distribution or otherwise making the
+ Covered Code available to a third party.
+
+ 1.1. "Contributor" means each entity that creates or contributes to
+ the creation of Modifications.
+
+ 1.2. "Contributor Version" means the combination of the Original
+ Code, prior Modifications used by a Contributor, and the Modifications
+ made by that particular Contributor.
+
+ 1.3. "Covered Code" means the Original Code or Modifications or the
+ combination of the Original Code and Modifications, in each case
+ including portions thereof.
+
+ 1.4. "Electronic Distribution Mechanism" means a mechanism generally
+ accepted in the software development community for the electronic
+ transfer of data.
+
+ 1.5. "Executable" means Covered Code in any form other than Source
+ Code.
+
+ 1.6. "Initial Developer" means the individual or entity identified
+ as the Initial Developer in the Source Code notice required by Exhibit
+ A.
+
+ 1.7. "Larger Work" means a work which combines Covered Code or
+ portions thereof with code not governed by the terms of this License.
+
+ 1.8. "License" means this document.
+
+ 1.8.1. "Licensable" means having the right to grant, to the maximum
+ extent possible, whether at the time of the initial grant or
+ subsequently acquired, any and all of the rights conveyed herein.
+
+ 1.9. "Modifications" means any addition to or deletion from the
+ substance or structure of either the Original Code or any previous
+ Modifications. When Covered Code is released as a series of files, a
+ Modification is:
+ A. Any addition to or deletion from the contents of a file
+ containing Original Code or previous Modifications.
+
+ B. Any new file that contains any part of the Original Code or
+ previous Modifications.
+
+ 1.10. "Original Code" means Source Code of computer software code
+ which is described in the Source Code notice required by Exhibit A as
+ Original Code, and which, at the time of its release under this
+ License is not already Covered Code governed by this License.
+
+ 1.10.1. "Patent Claims" means any patent claim(s), now owned or
+ hereafter acquired, including without limitation, method, process,
+ and apparatus claims, in any patent Licensable by grantor.
+
+ 1.11. "Source Code" means the preferred form of the Covered Code for
+ making modifications to it, including all modules it contains, plus
+ any associated interface definition files, scripts used to control
+ compilation and installation of an Executable, or source code
+ differential comparisons against either the Original Code or another
+ well known, available Covered Code of the Contributor's choice. The
+ Source Code can be in a compressed or archival form, provided the
+ appropriate decompression or de-archiving software is widely available
+ for no charge.
+
+ 1.12. "You" (or "Your") means an individual or a legal entity
+ exercising rights under, and complying with all of the terms of, this
+ License or a future version of this License issued under Section 6.1.
+ For legal entities, "You" includes any entity which controls, is
+ controlled by, or is under common control with You. For purposes of
+ this definition, "control" means (a) the power, direct or indirect,
+ to cause the direction or management of such entity, whether by
+ contract or otherwise, or (b) ownership of more than fifty percent
+ (50%) of the outstanding shares or beneficial ownership of such
+ entity.
+
+2. Source Code License.
+
+ 2.1. The Initial Developer Grant.
+ The Initial Developer hereby grants You a world-wide, royalty-free,
+ non-exclusive license, subject to third party intellectual property
+ claims:
+ (a) under intellectual property rights (other than patent or
+ trademark) Licensable by Initial Developer to use, reproduce,
+ modify, display, perform, sublicense and distribute the Original
+ Code (or portions thereof) with or without Modifications, and/or
+ as part of a Larger Work; and
+
+ (b) under Patents Claims infringed by the making, using or
+ selling of Original Code, to make, have made, use, practice,
+ sell, and offer for sale, and/or otherwise dispose of the
+ Original Code (or portions thereof).
+
+ (c) the licenses granted in this Section 2.1(a) and (b) are
+ effective on the date Initial Developer first distributes
+ Original Code under the terms of this License.
+
+ (d) Notwithstanding Section 2.1(b) above, no patent license is
+ granted: 1) for code that You delete from the Original Code; 2)
+ separate from the Original Code; or 3) for infringements caused
+ by: i) the modification of the Original Code or ii) the
+ combination of the Original Code with other software or devices.
+
+ 2.2. Contributor Grant.
+ Subject to third party intellectual property claims, each Contributor
+ hereby grants You a world-wide, royalty-free, non-exclusive license
+
+ (a) under intellectual property rights (other than patent or
+ trademark) Licensable by Contributor, to use, reproduce, modify,
+ display, perform, sublicense and distribute the Modifications
+ created by such Contributor (or portions thereof) either on an
+ unmodified basis, with other Modifications, as Covered Code
+ and/or as part of a Larger Work; and
+
+ (b) under Patent Claims infringed by the making, using, or
+ selling of Modifications made by that Contributor either alone
+ and/or in combination with its Contributor Version (or portions
+ of such combination), to make, use, sell, offer for sale, have
+ made, and/or otherwise dispose of: 1) Modifications made by that
+ Contributor (or portions thereof); and 2) the combination of
+ Modifications made by that Contributor with its Contributor
+ Version (or portions of such combination).
+
+ (c) the licenses granted in Sections 2.2(a) and 2.2(b) are
+ effective on the date Contributor first makes Commercial Use of
+ the Covered Code.
+
+ (d) Notwithstanding Section 2.2(b) above, no patent license is
+ granted: 1) for any code that Contributor has deleted from the
+ Contributor Version; 2) separate from the Contributor Version;
+ 3) for infringements caused by: i) third party modifications of
+ Contributor Version or ii) the combination of Modifications made
+ by that Contributor with other software (except as part of the
+ Contributor Version) or other devices; or 4) under Patent Claims
+ infringed by Covered Code in the absence of Modifications made by
+ that Contributor.
+
+3. Distribution Obligations.
+
+ 3.1. Application of License.
+ The Modifications which You create or to which You contribute are
+ governed by the terms of this License, including without limitation
+ Section 2.2. The Source Code version of Covered Code may be
+ distributed only under the terms of this License or a future version
+ of this License released under Section 6.1, and You must include a
+ copy of this License with every copy of the Source Code You
+ distribute. You may not offer or impose any terms on any Source Code
+ version that alters or restricts the applicable version of this
+ License or the recipients' rights hereunder. However, You may include
+ an additional document offering the additional rights described in
+ Section 3.5.
+
+ 3.2. Availability of Source Code.
+ Any Modification which You create or to which You contribute must be
+ made available in Source Code form under the terms of this License
+ either on the same media as an Executable version or via an accepted
+ Electronic Distribution Mechanism to anyone to whom you made an
+ Executable version available; and if made available via Electronic
+ Distribution Mechanism, must remain available for at least twelve (12)
+ months after the date it initially became available, or at least six
+ (6) months after a subsequent version of that particular Modification
+ has been made available to such recipients. You are responsible for
+ ensuring that the Source Code version remains available even if the
+ Electronic Distribution Mechanism is maintained by a third party.
+
+ 3.3. Description of Modifications.
+ You must cause all Covered Code to which You contribute to contain a
+ file documenting the changes You made to create that Covered Code and
+ the date of any change. You must include a prominent statement that
+ the Modification is derived, directly or indirectly, from Original
+ Code provided by the Initial Developer and including the name of the
+ Initial Developer in (a) the Source Code, and (b) in any notice in an
+ Executable version or related documentation in which You describe the
+ origin or ownership of the Covered Code.
+
+ 3.4. Intellectual Property Matters
+ (a) Third Party Claims.
+ If Contributor has knowledge that a license under a third party's
+ intellectual property rights is required to exercise the rights
+ granted by such Contributor under Sections 2.1 or 2.2,
+ Contributor must include a text file with the Source Code
+ distribution titled "LEGAL" which describes the claim and the
+ party making the claim in sufficient detail that a recipient will
+ know whom to contact. If Contributor obtains such knowledge after
+ the Modification is made available as described in Section 3.2,
+ Contributor shall promptly modify the LEGAL file in all copies
+ Contributor makes available thereafter and shall take other steps
+ (such as notifying appropriate mailing lists or newsgroups)
+ reasonably calculated to inform those who received the Covered
+ Code that new knowledge has been obtained.
+
+ (b) Contributor APIs.
+ If Contributor's Modifications include an application programming
+ interface and Contributor has knowledge of patent licenses which
+ are reasonably necessary to implement that API, Contributor must
+ also include this information in the LEGAL file.
+
+ (c) Representations.
+ Contributor represents that, except as disclosed pursuant to
+ Section 3.4(a) above, Contributor believes that Contributor's
+ Modifications are Contributor's original creation(s) and/or
+ Contributor has sufficient rights to grant the rights conveyed by
+ this License.
+
+ 3.5. Required Notices.
+ You must duplicate the notice in Exhibit A in each file of the Source
+ Code. If it is not possible to put such notice in a particular Source
+ Code file due to its structure, then You must include such notice in a
+ location (such as a relevant directory) where a user would be likely
+ to look for such a notice. If You created one or more Modification(s)
+ You may add your name as a Contributor to the notice described in
+ Exhibit A. You must also duplicate this License in any documentation
+ for the Source Code where You describe recipients' rights or ownership
+ rights relating to Covered Code. You may choose to offer, and to
+ charge a fee for, warranty, support, indemnity or liability
+ obligations to one or more recipients of Covered Code. However, You
+ may do so only on Your own behalf, and not on behalf of the Initial
+ Developer or any Contributor. You must make it absolutely clear than
+ any such warranty, support, indemnity or liability obligation is
+ offered by You alone, and You hereby agree to indemnify the Initial
+ Developer and every Contributor for any liability incurred by the
+ Initial Developer or such Contributor as a result of warranty,
+ support, indemnity or liability terms You offer.
+
+ 3.6. Distribution of Executable Versions.
+ You may distribute Covered Code in Executable form only if the
+ requirements of Section 3.1-3.5 have been met for that Covered Code,
+ and if You include a notice stating that the Source Code version of
+ the Covered Code is available under the terms of this License,
+ including a description of how and where You have fulfilled the
+ obligations of Section 3.2. The notice must be conspicuously included
+ in any notice in an Executable version, related documentation or
+ collateral in which You describe recipients' rights relating to the
+ Covered Code. You may distribute the Executable version of Covered
+ Code or ownership rights under a license of Your choice, which may
+ contain terms different from this License, provided that You are in
+ compliance with the terms of this License and that the license for the
+ Executable version does not attempt to limit or alter the recipient's
+ rights in the Source Code version from the rights set forth in this
+ License. If You distribute the Executable version under a different
+ license You must make it absolutely clear that any terms which differ
+ from this License are offered by You alone, not by the Initial
+ Developer or any Contributor. You hereby agree to indemnify the
+ Initial Developer and every Contributor for any liability incurred by
+ the Initial Developer or such Contributor as a result of any such
+ terms You offer.
+
+ 3.7. Larger Works.
+ You may create a Larger Work by combining Covered Code with other code
+ not governed by the terms of this License and distribute the Larger
+ Work as a single product. In such a case, You must make sure the
+ requirements of this License are fulfilled for the Covered Code.
+
+4. Inability to Comply Due to Statute or Regulation.
+
+ If it is impossible for You to comply with any of the terms of this
+ License with respect to some or all of the Covered Code due to
+ statute, judicial order, or regulation then You must: (a) comply with
+ the terms of this License to the maximum extent possible; and (b)
+ describe the limitations and the code they affect. Such description
+ must be included in the LEGAL file described in Section 3.4 and must
+ be included with all distributions of the Source Code. Except to the
+ extent prohibited by statute or regulation, such description must be
+ sufficiently detailed for a recipient of ordinary skill to be able to
+ understand it.
+
+5. Application of this License.
+
+ This License applies to code to which the Initial Developer has
+ attached the notice in Exhibit A and to related Covered Code.
+
+6. Versions of the License.
+
+ 6.1. New Versions.
+ Netscape Communications Corporation ("Netscape") may publish revised
+ and/or new versions of the License from time to time. Each version
+ will be given a distinguishing version number.
+
+ 6.2. Effect of New Versions.
+ Once Covered Code has been published under a particular version of the
+ License, You may always continue to use it under the terms of that
+ version. You may also choose to use such Covered Code under the terms
+ of any subsequent version of the License published by Netscape. No one
+ other than Netscape has the right to modify the terms applicable to
+ Covered Code created under this License.
+
+ 6.3. Derivative Works.
+ If You create or use a modified version of this License (which you may
+ only do in order to apply it to code which is not already Covered Code
+ governed by this License), You must (a) rename Your license so that
+ the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape",
+ "MPL", "NPL" or any confusingly similar phrase do not appear in your
+ license (except to note that your license differs from this License)
+ and (b) otherwise make it clear that Your version of the license
+ contains terms which differ from the Mozilla Public License and
+ Netscape Public License. (Filling in the name of the Initial
+ Developer, Original Code or Contributor in the notice described in
+ Exhibit A shall not of themselves be deemed to be modifications of
+ this License.)
+
+7. DISCLAIMER OF WARRANTY.
+
+ COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF
+ DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING.
+ THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE
+ IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT,
+ YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE
+ COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER
+ OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF
+ ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
+
+8. TERMINATION.
+
+ 8.1. This License and the rights granted hereunder will terminate
+ automatically if You fail to comply with terms herein and fail to cure
+ such breach within 30 days of becoming aware of the breach. All
+ sublicenses to the Covered Code which are properly granted shall
+ survive any termination of this License. Provisions which, by their
+ nature, must remain in effect beyond the termination of this License
+ shall survive.
+
+ 8.2. If You initiate litigation by asserting a patent infringement
+ claim (excluding declatory judgment actions) against Initial Developer
+ or a Contributor (the Initial Developer or Contributor against whom
+ You file such action is referred to as "Participant") alleging that:
+
+ (a) such Participant's Contributor Version directly or indirectly
+ infringes any patent, then any and all rights granted by such
+ Participant to You under Sections 2.1 and/or 2.2 of this License
+ shall, upon 60 days notice from Participant terminate prospectively,
+ unless if within 60 days after receipt of notice You either: (i)
+ agree in writing to pay Participant a mutually agreeable reasonable
+ royalty for Your past and future use of Modifications made by such
+ Participant, or (ii) withdraw Your litigation claim with respect to
+ the Contributor Version against such Participant. If within 60 days
+ of notice, a reasonable royalty and payment arrangement are not
+ mutually agreed upon in writing by the parties or the litigation claim
+ is not withdrawn, the rights granted by Participant to You under
+ Sections 2.1 and/or 2.2 automatically terminate at the expiration of
+ the 60 day notice period specified above.
+
+ (b) any software, hardware, or device, other than such Participant's
+ Contributor Version, directly or indirectly infringes any patent, then
+ any rights granted to You by such Participant under Sections 2.1(b)
+ and 2.2(b) are revoked effective as of the date You first made, used,
+ sold, distributed, or had made, Modifications made by that
+ Participant.
+
+ 8.3. If You assert a patent infringement claim against Participant
+ alleging that such Participant's Contributor Version directly or
+ indirectly infringes any patent where such claim is resolved (such as
+ by license or settlement) prior to the initiation of patent
+ infringement litigation, then the reasonable value of the licenses
+ granted by such Participant under Sections 2.1 or 2.2 shall be taken
+ into account in determining the amount or value of any payment or
+ license.
+
+ 8.4. In the event of termination under Sections 8.1 or 8.2 above,
+ all end user license agreements (excluding distributors and resellers)
+ which have been validly granted by You or any distributor hereunder
+ prior to termination shall survive termination.
+
+9. LIMITATION OF LIABILITY.
+
+ UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
+ (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL
+ DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE,
+ OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR
+ ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY
+ CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL,
+ WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
+ COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
+ INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF
+ LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY
+ RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW
+ PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE
+ EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO
+ THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
+
+10. U.S. GOVERNMENT END USERS.
+
+ The Covered Code is a "commercial item," as that term is defined in
+ 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer
+ software" and "commercial computer software documentation," as such
+ terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48
+ C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995),
+ all U.S. Government End Users acquire Covered Code with only those
+ rights set forth herein.
+
+11. MISCELLANEOUS.
+
+ This License represents the complete agreement concerning subject
+ matter hereof. If any provision of this License is held to be
+ unenforceable, such provision shall be reformed only to the extent
+ necessary to make it enforceable. This License shall be governed by
+ California law provisions (except to the extent applicable law, if
+ any, provides otherwise), excluding its conflict-of-law provisions.
+ With respect to disputes in which at least one party is a citizen of,
+ or an entity chartered or registered to do business in the United
+ States of America, any litigation relating to this License shall be
+ subject to the jurisdiction of the Federal Courts of the Northern
+ District of California, with venue lying in Santa Clara County,
+ California, with the losing party responsible for costs, including
+ without limitation, court costs and reasonable attorneys' fees and
+ expenses. The application of the United Nations Convention on
+ Contracts for the International Sale of Goods is expressly excluded.
+ Any law or regulation which provides that the language of a contract
+ shall be construed against the drafter shall not apply to this
+ License.
+
+12. RESPONSIBILITY FOR CLAIMS.
+
+ As between Initial Developer and the Contributors, each party is
+ responsible for claims and damages arising, directly or indirectly,
+ out of its utilization of rights under this License and You agree to
+ work with Initial Developer and Contributors to distribute such
+ responsibility on an equitable basis. Nothing herein is intended or
+ shall be deemed to constitute any admission of liability.
+
+13. MULTIPLE-LICENSED CODE.
+
+ Initial Developer may designate portions of the Covered Code as
+ "Multiple-Licensed". "Multiple-Licensed" means that the Initial
+ Developer permits you to utilize portions of the Covered Code under
+ Your choice of the NPL or the alternative licenses, if any, specified
+ by the Initial Developer in the file described in Exhibit A.
+
+EXHIBIT A -Mozilla Public License.
+
+ ``The contents of this file are subject to the Mozilla Public License
+ Version 1.1 (the "License"); you may not use this file except in
+ compliance with the License. You may obtain a copy of the License at
+ http://www.mozilla.org/MPL/
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ License for the specific language governing rights and limitations
+ under the License.
+
+ The Original Code is ______________________________________.
+
+ The Initial Developer of the Original Code is ________________________.
+ Portions created by ______________________ are Copyright (C) ______
+ _______________________. All Rights Reserved.
+
+ Contributor(s): ______________________________________.
+
+ Alternatively, the contents of this file may be used under the terms
+ of the _____ license (the "[___] License"), in which case the
+ provisions of [______] License are applicable instead of those
+ above. If you wish to allow use of your version of this file only
+ under the terms of the [____] License and not to allow others to use
+ your version of this file under the MPL, indicate your decision by
+ deleting the provisions above and replace them with the notice and
+ other provisions required by the [___] License. If you do not delete
+ the provisions above, a recipient may use your version of this file
+ under either the MPL or the [___] License."
+
+ [NOTE: The text of this Exhibit A may differ slightly from the text of
+ the notices in the Source Code files of the Original Code. You should
+ use the text of this Exhibit A rather than the text found in the
+ Original Code Source Code for Your Modifications.]
+
diff --git a/packages/sdl/Makefile b/packages/sdl/Makefile
new file mode 100644
index 0000000000..e05c656714
--- /dev/null
+++ b/packages/sdl/Makefile
@@ -0,0 +1,2444 @@
+#
+# Don't edit, this file is generated by FPCMake Version 2.0.0 [2008/01/26]
+#
+default: all
+MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-netbsd i386-solaris i386-qnx i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian m68k-linux m68k-freebsd m68k-netbsd m68k-amiga m68k-atari m68k-openbsd m68k-palmos m68k-embedded powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macos powerpc-darwin powerpc-morphos powerpc-embedded sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-darwin x86_64-win64 x86_64-embedded arm-linux arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian powerpc64-linux powerpc64-darwin powerpc64-embedded
+BSDs = freebsd netbsd openbsd darwin
+UNIXs = linux $(BSDs) solaris qnx
+LIMIT83fs = go32v2 os2 emx watcom
+OSNeedsComspecToRunBatch = go32v2 watcom
+FORCE:
+.PHONY: FORCE
+override PATH:=$(patsubst %/,%,$(subst \,/,$(PATH)))
+ifneq ($(findstring darwin,$(OSTYPE)),)
+inUnix=1 #darwin
+SEARCHPATH:=$(filter-out .,$(subst :, ,$(PATH)))
+else
+ifeq ($(findstring ;,$(PATH)),)
+inUnix=1
+SEARCHPATH:=$(filter-out .,$(subst :, ,$(PATH)))
+else
+SEARCHPATH:=$(subst ;, ,$(PATH))
+endif
+endif
+SEARCHPATH+=$(patsubst %/,%,$(subst \,/,$(dir $(MAKE))))
+PWD:=$(strip $(wildcard $(addsuffix /pwd.exe,$(SEARCHPATH))))
+ifeq ($(PWD),)
+PWD:=$(strip $(wildcard $(addsuffix /pwd,$(SEARCHPATH))))
+ifeq ($(PWD),)
+$(error You need the GNU utils package to use this Makefile)
+else
+PWD:=$(firstword $(PWD))
+SRCEXEEXT=
+endif
+else
+PWD:=$(firstword $(PWD))
+SRCEXEEXT=.exe
+endif
+ifndef inUnix
+ifeq ($(OS),Windows_NT)
+inWinNT=1
+else
+ifdef OS2_SHELL
+inOS2=1
+endif
+endif
+else
+ifneq ($(findstring cygdrive,$(PATH)),)
+inCygWin=1
+endif
+endif
+ifdef inUnix
+SRCBATCHEXT=.sh
+else
+ifdef inOS2
+SRCBATCHEXT=.cmd
+else
+SRCBATCHEXT=.bat
+endif
+endif
+ifdef COMSPEC
+ifneq ($(findstring $(OS_SOURCE),$(OSNeedsComspecToRunBatch)),)
+RUNBATCH=$(COMSPEC) /C
+endif
+endif
+ifdef inUnix
+PATHSEP=/
+else
+PATHSEP:=$(subst /,\,/)
+ifdef inCygWin
+PATHSEP=/
+endif
+endif
+ifdef PWD
+BASEDIR:=$(subst \,/,$(shell $(PWD)))
+ifdef inCygWin
+ifneq ($(findstring /cygdrive/,$(BASEDIR)),)
+BASENODIR:=$(patsubst /cygdrive%,%,$(BASEDIR))
+BASEDRIVE:=$(firstword $(subst /, ,$(BASENODIR)))
+BASEDIR:=$(subst /cygdrive/$(BASEDRIVE)/,$(BASEDRIVE):/,$(BASEDIR))
+endif
+endif
+else
+BASEDIR=.
+endif
+ifdef inOS2
+ifndef ECHO
+ECHO:=$(strip $(wildcard $(addsuffix /gecho$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(ECHO),)
+ECHO:=$(strip $(wildcard $(addsuffix /echo$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(ECHO),)
+ECHO=echo
+else
+ECHO:=$(firstword $(ECHO))
+endif
+else
+ECHO:=$(firstword $(ECHO))
+endif
+endif
+export ECHO
+endif
+override DEFAULT_FPCDIR=../..
+ifndef FPC
+ifdef PP
+FPC=$(PP)
+endif
+endif
+ifndef FPC
+FPCPROG:=$(strip $(wildcard $(addsuffix /fpc$(SRCEXEEXT),$(SEARCHPATH))))
+ifneq ($(FPCPROG),)
+FPCPROG:=$(firstword $(FPCPROG))
+ifneq ($(CPU_TARGET),)
+FPC:=$(shell $(FPCPROG) -P$(CPU_TARGET) -PB)
+else
+FPC:=$(shell $(FPCPROG) -PB)
+endif
+ifneq ($(findstring Error,$(FPC)),)
+override FPC=$(firstword $(strip $(wildcard $(addsuffix /ppc386$(SRCEXEEXT),$(SEARCHPATH)))))
+endif
+else
+override FPC=$(firstword $(strip $(wildcard $(addsuffix /ppc386$(SRCEXEEXT),$(SEARCHPATH)))))
+endif
+endif
+override FPC:=$(subst $(SRCEXEEXT),,$(FPC))
+override FPC:=$(subst \,/,$(FPC))$(SRCEXEEXT)
+FOUNDFPC:=$(strip $(wildcard $(FPC)))
+ifeq ($(FOUNDFPC),)
+FOUNDFPC=$(strip $(wildcard $(addsuffix /$(FPC),$(SEARCHPATH))))
+ifeq ($(FOUNDFPC),)
+$(error Compiler $(FPC) not found)
+endif
+endif
+ifndef FPC_COMPILERINFO
+FPC_COMPILERINFO:=$(shell $(FPC) -iVSPTPSOTO)
+endif
+ifndef FPC_VERSION
+FPC_VERSION:=$(word 1,$(FPC_COMPILERINFO))
+endif
+export FPC FPC_VERSION FPC_COMPILERINFO
+unexport CHECKDEPEND ALLDEPENDENCIES
+ifndef CPU_TARGET
+ifdef CPU_TARGET_DEFAULT
+CPU_TARGET=$(CPU_TARGET_DEFAULT)
+endif
+endif
+ifndef OS_TARGET
+ifdef OS_TARGET_DEFAULT
+OS_TARGET=$(OS_TARGET_DEFAULT)
+endif
+endif
+ifneq ($(words $(FPC_COMPILERINFO)),5)
+FPC_COMPILERINFO+=$(shell $(FPC) -iSP)
+FPC_COMPILERINFO+=$(shell $(FPC) -iTP)
+FPC_COMPILERINFO+=$(shell $(FPC) -iSO)
+FPC_COMPILERINFO+=$(shell $(FPC) -iTO)
+endif
+ifndef CPU_SOURCE
+CPU_SOURCE:=$(word 2,$(FPC_COMPILERINFO))
+endif
+ifndef CPU_TARGET
+CPU_TARGET:=$(word 3,$(FPC_COMPILERINFO))
+endif
+ifndef OS_SOURCE
+OS_SOURCE:=$(word 4,$(FPC_COMPILERINFO))
+endif
+ifndef OS_TARGET
+OS_TARGET:=$(word 5,$(FPC_COMPILERINFO))
+endif
+FULL_TARGET=$(CPU_TARGET)-$(OS_TARGET)
+FULL_SOURCE=$(CPU_SOURCE)-$(OS_SOURCE)
+ifneq ($(findstring $(OS_SOURCE),$(LIMIT83fs)),)
+TARGETSUFFIX=$(OS_TARGET)
+SOURCESUFFIX=$(OS_SOURCE)
+else
+TARGETSUFFIX=$(FULL_TARGET)
+SOURCESUFFIX=$(FULL_SOURCE)
+endif
+ifneq ($(FULL_TARGET),$(FULL_SOURCE))
+CROSSCOMPILE=1
+endif
+ifeq ($(findstring makefile,$(MAKECMDGOALS)),)
+ifeq ($(findstring $(FULL_TARGET),$(MAKEFILETARGETS)),)
+$(error The Makefile doesn't support target $(FULL_TARGET), please run fpcmake first)
+endif
+endif
+ifneq ($(findstring $(OS_TARGET),$(BSDs)),)
+BSDhier=1
+endif
+ifeq ($(OS_TARGET),linux)
+linuxHier=1
+endif
+export OS_TARGET OS_SOURCE CPU_TARGET CPU_SOURCE FULL_TARGET FULL_SOURCE TARGETSUFFIX SOURCESUFFIX CROSSCOMPILE
+ifdef FPCDIR
+override FPCDIR:=$(subst \,/,$(FPCDIR))
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+override FPCDIR=wrong
+endif
+else
+override FPCDIR=wrong
+endif
+ifdef DEFAULT_FPCDIR
+ifeq ($(FPCDIR),wrong)
+override FPCDIR:=$(subst \,/,$(DEFAULT_FPCDIR))
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+override FPCDIR=wrong
+endif
+endif
+endif
+ifeq ($(FPCDIR),wrong)
+ifdef inUnix
+override FPCDIR=/usr/local/lib/fpc/$(FPC_VERSION)
+ifeq ($(wildcard $(FPCDIR)/units),)
+override FPCDIR=/usr/lib/fpc/$(FPC_VERSION)
+endif
+else
+override FPCDIR:=$(subst /$(FPC),,$(firstword $(strip $(wildcard $(addsuffix /$(FPC),$(SEARCHPATH))))))
+override FPCDIR:=$(FPCDIR)/..
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+override FPCDIR:=$(FPCDIR)/..
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+override FPCDIR:=$(BASEDIR)
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+override FPCDIR=c:/pp
+endif
+endif
+endif
+endif
+endif
+ifndef CROSSBINDIR
+CROSSBINDIR:=$(wildcard $(FPCDIR)/bin/$(TARGETSUFFIX))
+endif
+ifndef BINUTILSPREFIX
+ifndef CROSSBINDIR
+ifdef CROSSCOMPILE
+BINUTILSPREFIX=$(CPU_TARGET)-$(OS_TARGET)-
+endif
+endif
+endif
+UNITSDIR:=$(wildcard $(FPCDIR)/units/$(TARGETSUFFIX))
+ifeq ($(UNITSDIR),)
+UNITSDIR:=$(wildcard $(FPCDIR)/units/$(OS_TARGET))
+endif
+PACKAGESDIR:=$(wildcard $(FPCDIR) $(FPCDIR)/packages $(FPCDIR)/packages/base $(FPCDIR)/packages/extra)
+override PACKAGE_NAME=sdl
+override PACKAGE_VERSION=1.0.0
+ifeq ($(FULL_TARGET),i386-linux)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger sdlutils
+endif
+ifeq ($(FULL_TARGET),i386-go32v2)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+endif
+ifeq ($(FULL_TARGET),i386-win32)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger sdlutils
+endif
+ifeq ($(FULL_TARGET),i386-os2)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+endif
+ifeq ($(FULL_TARGET),i386-freebsd)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger sdlutils
+endif
+ifeq ($(FULL_TARGET),i386-beos)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+endif
+ifeq ($(FULL_TARGET),i386-netbsd)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+endif
+ifeq ($(FULL_TARGET),i386-solaris)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+endif
+ifeq ($(FULL_TARGET),i386-qnx)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+endif
+ifeq ($(FULL_TARGET),i386-netware)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+endif
+ifeq ($(FULL_TARGET),i386-openbsd)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+endif
+ifeq ($(FULL_TARGET),i386-wdosx)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+endif
+ifeq ($(FULL_TARGET),i386-darwin)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger sdlutils
+endif
+ifeq ($(FULL_TARGET),i386-emx)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+endif
+ifeq ($(FULL_TARGET),i386-watcom)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+endif
+ifeq ($(FULL_TARGET),i386-netwlibc)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+endif
+ifeq ($(FULL_TARGET),i386-wince)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+endif
+ifeq ($(FULL_TARGET),i386-embedded)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+endif
+ifeq ($(FULL_TARGET),i386-symbian)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+endif
+ifeq ($(FULL_TARGET),m68k-linux)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+endif
+ifeq ($(FULL_TARGET),m68k-freebsd)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+endif
+ifeq ($(FULL_TARGET),m68k-netbsd)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+endif
+ifeq ($(FULL_TARGET),m68k-amiga)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+endif
+ifeq ($(FULL_TARGET),m68k-atari)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+endif
+ifeq ($(FULL_TARGET),m68k-openbsd)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+endif
+ifeq ($(FULL_TARGET),m68k-palmos)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+endif
+ifeq ($(FULL_TARGET),m68k-embedded)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+endif
+ifeq ($(FULL_TARGET),powerpc-linux)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger sdlutils
+endif
+ifeq ($(FULL_TARGET),powerpc-netbsd)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+endif
+ifeq ($(FULL_TARGET),powerpc-amiga)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+endif
+ifeq ($(FULL_TARGET),powerpc-macos)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+endif
+ifeq ($(FULL_TARGET),powerpc-darwin)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger sdlutils
+endif
+ifeq ($(FULL_TARGET),powerpc-morphos)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+endif
+ifeq ($(FULL_TARGET),powerpc-embedded)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+endif
+ifeq ($(FULL_TARGET),sparc-linux)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+endif
+ifeq ($(FULL_TARGET),sparc-netbsd)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+endif
+ifeq ($(FULL_TARGET),sparc-solaris)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+endif
+ifeq ($(FULL_TARGET),sparc-embedded)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+endif
+ifeq ($(FULL_TARGET),x86_64-linux)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+endif
+ifeq ($(FULL_TARGET),x86_64-freebsd)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+endif
+ifeq ($(FULL_TARGET),x86_64-darwin)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+endif
+ifeq ($(FULL_TARGET),x86_64-win64)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+endif
+ifeq ($(FULL_TARGET),x86_64-embedded)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+endif
+ifeq ($(FULL_TARGET),arm-linux)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+endif
+ifeq ($(FULL_TARGET),arm-palmos)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+endif
+ifeq ($(FULL_TARGET),arm-wince)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+endif
+ifeq ($(FULL_TARGET),arm-gba)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+endif
+ifeq ($(FULL_TARGET),arm-nds)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+endif
+ifeq ($(FULL_TARGET),arm-embedded)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+endif
+ifeq ($(FULL_TARGET),arm-symbian)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+endif
+ifeq ($(FULL_TARGET),powerpc64-linux)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+endif
+ifeq ($(FULL_TARGET),powerpc64-darwin)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+endif
+ifeq ($(FULL_TARGET),powerpc64-embedded)
+override TARGET_UNITS+=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+endif
+override INSTALL_FPCPACKAGE=y
+ifeq ($(FULL_TARGET),i386-linux)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-go32v2)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-win32)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-os2)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-freebsd)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-beos)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-netbsd)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-solaris)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-qnx)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-netware)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-openbsd)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-wdosx)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-darwin)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-emx)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-watcom)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-netwlibc)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-wince)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-embedded)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-symbian)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),m68k-linux)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),m68k-freebsd)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),m68k-netbsd)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),m68k-amiga)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),m68k-atari)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),m68k-openbsd)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),m68k-palmos)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),m68k-embedded)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),powerpc-linux)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),powerpc-netbsd)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),powerpc-amiga)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),powerpc-macos)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),powerpc-darwin)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),powerpc-morphos)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),powerpc-embedded)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),sparc-linux)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),sparc-netbsd)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),sparc-solaris)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),sparc-embedded)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),x86_64-linux)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),x86_64-freebsd)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),x86_64-darwin)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),x86_64-win64)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),x86_64-embedded)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),arm-linux)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),arm-palmos)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),arm-wince)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),arm-gba)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),arm-nds)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),arm-embedded)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),arm-symbian)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),powerpc64-linux)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),powerpc64-darwin)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),powerpc64-embedded)
+override COMPILER_INCLUDEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-linux)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),i386-go32v2)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),i386-win32)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),i386-os2)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),i386-freebsd)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),i386-beos)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),i386-netbsd)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),i386-solaris)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),i386-qnx)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),i386-netware)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),i386-openbsd)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),i386-wdosx)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),i386-darwin)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),i386-emx)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),i386-watcom)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),i386-netwlibc)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),i386-wince)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),i386-embedded)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),i386-symbian)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),m68k-linux)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),m68k-freebsd)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),m68k-netbsd)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),m68k-amiga)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),m68k-atari)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),m68k-openbsd)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),m68k-palmos)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),m68k-embedded)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),powerpc-linux)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),powerpc-netbsd)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),powerpc-amiga)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),powerpc-macos)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),powerpc-darwin)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),powerpc-morphos)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),powerpc-embedded)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),sparc-linux)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),sparc-netbsd)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),sparc-solaris)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),sparc-embedded)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),x86_64-linux)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),x86_64-freebsd)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),x86_64-darwin)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),x86_64-win64)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),x86_64-embedded)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),arm-linux)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),arm-palmos)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),arm-wince)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),arm-gba)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),arm-nds)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),arm-embedded)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),arm-symbian)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),powerpc64-linux)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),powerpc64-darwin)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifeq ($(FULL_TARGET),powerpc64-embedded)
+override COMPILER_SOURCEDIR+=src tests
+endif
+ifdef REQUIRE_UNITSDIR
+override UNITSDIR+=$(REQUIRE_UNITSDIR)
+endif
+ifdef REQUIRE_PACKAGESDIR
+override PACKAGESDIR+=$(REQUIRE_PACKAGESDIR)
+endif
+ifdef ZIPINSTALL
+ifneq ($(findstring $(OS_TARGET),$(UNIXs)),)
+UNIXHier=1
+endif
+else
+ifneq ($(findstring $(OS_SOURCE),$(UNIXs)),)
+UNIXHier=1
+endif
+endif
+ifndef INSTALL_PREFIX
+ifdef PREFIX
+INSTALL_PREFIX=$(PREFIX)
+endif
+endif
+ifndef INSTALL_PREFIX
+ifdef UNIXHier
+INSTALL_PREFIX=/usr/local
+else
+ifdef INSTALL_FPCPACKAGE
+INSTALL_BASEDIR:=/pp
+else
+INSTALL_BASEDIR:=/$(PACKAGE_NAME)
+endif
+endif
+endif
+export INSTALL_PREFIX
+ifdef INSTALL_FPCSUBDIR
+export INSTALL_FPCSUBDIR
+endif
+ifndef DIST_DESTDIR
+DIST_DESTDIR:=$(BASEDIR)
+endif
+export DIST_DESTDIR
+ifndef COMPILER_UNITTARGETDIR
+ifdef PACKAGEDIR_MAIN
+COMPILER_UNITTARGETDIR=$(PACKAGEDIR_MAIN)/units/$(TARGETSUFFIX)
+else
+COMPILER_UNITTARGETDIR=units/$(TARGETSUFFIX)
+endif
+endif
+ifndef COMPILER_TARGETDIR
+COMPILER_TARGETDIR=.
+endif
+ifndef INSTALL_BASEDIR
+ifdef UNIXHier
+ifdef INSTALL_FPCPACKAGE
+INSTALL_BASEDIR:=$(INSTALL_PREFIX)/lib/fpc/$(FPC_VERSION)
+else
+INSTALL_BASEDIR:=$(INSTALL_PREFIX)/lib/$(PACKAGE_NAME)
+endif
+else
+INSTALL_BASEDIR:=$(INSTALL_PREFIX)
+endif
+endif
+ifndef INSTALL_BINDIR
+ifdef UNIXHier
+INSTALL_BINDIR:=$(INSTALL_PREFIX)/bin
+else
+INSTALL_BINDIR:=$(INSTALL_BASEDIR)/bin
+ifdef INSTALL_FPCPACKAGE
+ifdef CROSSCOMPILE
+ifdef CROSSINSTALL
+INSTALL_BINDIR:=$(INSTALL_BINDIR)/$(SOURCESUFFIX)
+else
+INSTALL_BINDIR:=$(INSTALL_BINDIR)/$(TARGETSUFFIX)
+endif
+else
+INSTALL_BINDIR:=$(INSTALL_BINDIR)/$(TARGETSUFFIX)
+endif
+endif
+endif
+endif
+ifndef INSTALL_UNITDIR
+INSTALL_UNITDIR:=$(INSTALL_BASEDIR)/units/$(TARGETSUFFIX)
+ifdef INSTALL_FPCPACKAGE
+ifdef PACKAGE_NAME
+INSTALL_UNITDIR:=$(INSTALL_UNITDIR)/$(PACKAGE_NAME)
+endif
+endif
+endif
+ifndef INSTALL_LIBDIR
+ifdef UNIXHier
+INSTALL_LIBDIR:=$(INSTALL_PREFIX)/lib
+else
+INSTALL_LIBDIR:=$(INSTALL_UNITDIR)
+endif
+endif
+ifndef INSTALL_SOURCEDIR
+ifdef UNIXHier
+ifdef BSDhier
+SRCPREFIXDIR=share/src
+else
+ifdef linuxHier
+SRCPREFIXDIR=share/src
+else
+SRCPREFIXDIR=src
+endif
+endif
+ifdef INSTALL_FPCPACKAGE
+ifdef INSTALL_FPCSUBDIR
+INSTALL_SOURCEDIR:=$(INSTALL_PREFIX)/$(SRCPREFIXDIR)/fpc-$(FPC_VERSION)/$(INSTALL_FPCSUBDIR)/$(PACKAGE_NAME)
+else
+INSTALL_SOURCEDIR:=$(INSTALL_PREFIX)/$(SRCPREFIXDIR)/fpc-$(FPC_VERSION)/$(PACKAGE_NAME)
+endif
+else
+INSTALL_SOURCEDIR:=$(INSTALL_PREFIX)/$(SRCPREFIXDIR)/$(PACKAGE_NAME)-$(PACKAGE_VERSION)
+endif
+else
+ifdef INSTALL_FPCPACKAGE
+ifdef INSTALL_FPCSUBDIR
+INSTALL_SOURCEDIR:=$(INSTALL_BASEDIR)/source/$(INSTALL_FPCSUBDIR)/$(PACKAGE_NAME)
+else
+INSTALL_SOURCEDIR:=$(INSTALL_BASEDIR)/source/$(PACKAGE_NAME)
+endif
+else
+INSTALL_SOURCEDIR:=$(INSTALL_BASEDIR)/source
+endif
+endif
+endif
+ifndef INSTALL_DOCDIR
+ifdef UNIXHier
+ifdef BSDhier
+DOCPREFIXDIR=share/doc
+else
+ifdef linuxHier
+DOCPREFIXDIR=share/doc
+else
+DOCPREFIXDIR=doc
+endif
+endif
+ifdef INSTALL_FPCPACKAGE
+INSTALL_DOCDIR:=$(INSTALL_PREFIX)/$(DOCPREFIXDIR)/fpc-$(FPC_VERSION)/$(PACKAGE_NAME)
+else
+INSTALL_DOCDIR:=$(INSTALL_PREFIX)/$(DOCPREFIXDIR)/$(PACKAGE_NAME)-$(PACKAGE_VERSION)
+endif
+else
+ifdef INSTALL_FPCPACKAGE
+INSTALL_DOCDIR:=$(INSTALL_BASEDIR)/doc/$(PACKAGE_NAME)
+else
+INSTALL_DOCDIR:=$(INSTALL_BASEDIR)/doc
+endif
+endif
+endif
+ifndef INSTALL_EXAMPLEDIR
+ifdef UNIXHier
+ifdef INSTALL_FPCPACKAGE
+ifdef BSDhier
+INSTALL_EXAMPLEDIR:=$(INSTALL_PREFIX)/share/examples/fpc-$(FPC_VERSION)/$(PACKAGE_NAME)
+else
+ifdef linuxHier
+INSTALL_EXAMPLEDIR:=$(INSTALL_DOCDIR)/examples
+else
+INSTALL_EXAMPLEDIR:=$(INSTALL_PREFIX)/doc/fpc-$(FPC_VERSION)/examples/$(PACKAGE_NAME)
+endif
+endif
+else
+ifdef BSDhier
+INSTALL_EXAMPLEDIR:=$(INSTALL_PREFIX)/share/examples/$(PACKAGE_NAME)-$(PACKAGE_VERSION)
+else
+ifdef linuxHier
+INSTALL_EXAMPLEDIR:=$(INSTALL_DOCDIR)/examples/$(PACKAGE_NAME)-$(PACKAGE_VERSION)
+else
+INSTALL_EXAMPLEDIR:=$(INSTALL_PREFIX)/doc/$(PACKAGE_NAME)-$(PACKAGE_VERSION)
+endif
+endif
+endif
+else
+ifdef INSTALL_FPCPACKAGE
+INSTALL_EXAMPLEDIR:=$(INSTALL_BASEDIR)/examples/$(PACKAGE_NAME)
+else
+INSTALL_EXAMPLEDIR:=$(INSTALL_BASEDIR)/examples
+endif
+endif
+endif
+ifndef INSTALL_DATADIR
+INSTALL_DATADIR=$(INSTALL_BASEDIR)
+endif
+ifndef INSTALL_SHAREDDIR
+INSTALL_SHAREDDIR=$(INSTALL_PREFIX)/lib
+endif
+ifdef CROSSCOMPILE
+ifndef CROSSBINDIR
+CROSSBINDIR:=$(wildcard $(CROSSTARGETDIR)/bin/$(SOURCESUFFIX))
+ifeq ($(CROSSBINDIR),)
+CROSSBINDIR:=$(wildcard $(INSTALL_BASEDIR)/cross/$(TARGETSUFFIX)/bin/$(FULL_SOURCE))
+endif
+endif
+else
+CROSSBINDIR=
+endif
+ifeq ($(OS_SOURCE),linux)
+ifndef GCCLIBDIR
+ifeq ($(CPU_TARGET),i386)
+ifneq ($(findstring x86_64,$(shell uname -a)),)
+ifeq ($(BINUTILSPREFIX),)
+GCCLIBDIR:=$(shell dirname `gcc -m32 -print-libgcc-file-name`)
+endif
+endif
+endif
+ifeq ($(CPU_TARGET),powerpc64)
+ifeq ($(BINUTILSPREFIX),)
+GCCLIBDIR:=$(shell dirname `gcc -m64 -print-libgcc-file-name`)
+endif
+endif
+endif
+ifndef GCCLIBDIR
+CROSSGCC=$(strip $(wildcard $(addsuffix /$(BINUTILSPREFIX)gcc$(SRCEXEEXT),$(SEARCHPATH))))
+ifneq ($(CROSSGCC),)
+GCCLIBDIR:=$(shell dirname `$(CROSSGCC) -print-libgcc-file-name`)
+endif
+endif
+ifndef OTHERLIBDIR
+OTHERLIBDIR:=$(shell grep -v "^\#" /etc/ld.so.conf | awk '{ ORS=" "; print $1 }')
+endif
+endif
+ifdef inUnix
+ifeq ($(OS_SOURCE),netbsd)
+OTHERLIBDIR+=/usr/pkg/lib
+endif
+export GCCLIBDIR OTHERLIB
+endif
+BATCHEXT=.bat
+LOADEREXT=.as
+EXEEXT=.exe
+PPLEXT=.ppl
+PPUEXT=.ppu
+OEXT=.o
+ASMEXT=.s
+SMARTEXT=.sl
+STATICLIBEXT=.a
+SHAREDLIBEXT=.so
+SHAREDLIBPREFIX=libfp
+STATICLIBPREFIX=libp
+IMPORTLIBPREFIX=libimp
+RSTEXT=.rst
+ifeq ($(findstring 1.0.,$(FPC_VERSION)),)
+ifeq ($(OS_TARGET),go32v1)
+STATICLIBPREFIX=
+SHORTSUFFIX=v1
+endif
+ifeq ($(OS_TARGET),go32v2)
+STATICLIBPREFIX=
+SHORTSUFFIX=dos
+endif
+ifeq ($(OS_TARGET),watcom)
+STATICLIBPREFIX=
+OEXT=.obj
+ASMEXT=.asm
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=wat
+endif
+ifeq ($(OS_TARGET),linux)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=lnx
+endif
+ifeq ($(OS_TARGET),freebsd)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=fbs
+endif
+ifeq ($(OS_TARGET),netbsd)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=nbs
+endif
+ifeq ($(OS_TARGET),openbsd)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=obs
+endif
+ifeq ($(OS_TARGET),win32)
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=w32
+endif
+ifeq ($(OS_TARGET),os2)
+BATCHEXT=.cmd
+AOUTEXT=.out
+STATICLIBPREFIX=
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=os2
+ECHO=echo
+endif
+ifeq ($(OS_TARGET),emx)
+BATCHEXT=.cmd
+AOUTEXT=.out
+STATICLIBPREFIX=
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=emx
+ECHO=echo
+endif
+ifeq ($(OS_TARGET),amiga)
+EXEEXT=
+SHAREDLIBEXT=.library
+SHORTSUFFIX=amg
+endif
+ifeq ($(OS_TARGET),morphos)
+EXEEXT=
+SHAREDLIBEXT=.library
+SHORTSUFFIX=mos
+endif
+ifeq ($(OS_TARGET),atari)
+EXEEXT=.ttp
+SHORTSUFFIX=ata
+endif
+ifeq ($(OS_TARGET),beos)
+BATCHEXT=.sh
+EXEEXT=
+SHORTSUFFIX=be
+endif
+ifeq ($(OS_TARGET),solaris)
+BATCHEXT=.sh
+EXEEXT=
+SHORTSUFFIX=sun
+endif
+ifeq ($(OS_TARGET),qnx)
+BATCHEXT=.sh
+EXEEXT=
+SHORTSUFFIX=qnx
+endif
+ifeq ($(OS_TARGET),netware)
+EXEEXT=.nlm
+STATICLIBPREFIX=
+SHORTSUFFIX=nw
+endif
+ifeq ($(OS_TARGET),netwlibc)
+EXEEXT=.nlm
+STATICLIBPREFIX=
+SHORTSUFFIX=nwl
+endif
+ifeq ($(OS_TARGET),macos)
+BATCHEXT=
+EXEEXT=
+DEBUGSYMEXT=.xcoff
+SHORTSUFFIX=mac
+endif
+ifeq ($(OS_TARGET),darwin)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=dwn
+endif
+ifeq ($(OS_TARGET),gba)
+EXEEXT=.gba
+SHAREDLIBEXT=.so
+SHORTSUFFIX=gba
+endif
+ifeq ($(OS_TARGET),symbian)
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=symbian
+endif
+else
+ifeq ($(OS_TARGET),go32v1)
+PPUEXT=.pp1
+OEXT=.o1
+ASMEXT=.s1
+SMARTEXT=.sl1
+STATICLIBEXT=.a1
+SHAREDLIBEXT=.so1
+STATICLIBPREFIX=
+SHORTSUFFIX=v1
+endif
+ifeq ($(OS_TARGET),go32v2)
+STATICLIBPREFIX=
+SHORTSUFFIX=dos
+endif
+ifeq ($(OS_TARGET),watcom)
+STATICLIBPREFIX=
+SHORTSUFFIX=wat
+endif
+ifeq ($(OS_TARGET),linux)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=lnx
+endif
+ifeq ($(OS_TARGET),freebsd)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=fbs
+endif
+ifeq ($(OS_TARGET),netbsd)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=nbs
+endif
+ifeq ($(OS_TARGET),openbsd)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=obs
+endif
+ifeq ($(OS_TARGET),win32)
+PPUEXT=.ppw
+OEXT=.ow
+ASMEXT=.sw
+SMARTEXT=.slw
+STATICLIBEXT=.aw
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=w32
+endif
+ifeq ($(OS_TARGET),os2)
+BATCHEXT=.cmd
+PPUEXT=.ppo
+ASMEXT=.so2
+OEXT=.oo2
+AOUTEXT=.out
+SMARTEXT=.sl2
+STATICLIBPREFIX=
+STATICLIBEXT=.ao2
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=os2
+ECHO=echo
+endif
+ifeq ($(OS_TARGET),amiga)
+EXEEXT=
+PPUEXT=.ppu
+ASMEXT=.s
+OEXT=.o
+SMARTEXT=.sl
+STATICLIBEXT=.a
+SHAREDLIBEXT=.library
+SHORTSUFFIX=amg
+endif
+ifeq ($(OS_TARGET),atari)
+PPUEXT=.ppu
+ASMEXT=.s
+OEXT=.o
+SMARTEXT=.sl
+STATICLIBEXT=.a
+EXEEXT=.ttp
+SHORTSUFFIX=ata
+endif
+ifeq ($(OS_TARGET),beos)
+BATCHEXT=.sh
+PPUEXT=.ppu
+ASMEXT=.s
+OEXT=.o
+SMARTEXT=.sl
+STATICLIBEXT=.a
+EXEEXT=
+SHORTSUFFIX=be
+endif
+ifeq ($(OS_TARGET),solaris)
+BATCHEXT=.sh
+PPUEXT=.ppu
+ASMEXT=.s
+OEXT=.o
+SMARTEXT=.sl
+STATICLIBEXT=.a
+EXEEXT=
+SHORTSUFFIX=sun
+endif
+ifeq ($(OS_TARGET),qnx)
+BATCHEXT=.sh
+PPUEXT=.ppu
+ASMEXT=.s
+OEXT=.o
+SMARTEXT=.sl
+STATICLIBEXT=.a
+EXEEXT=
+SHORTSUFFIX=qnx
+endif
+ifeq ($(OS_TARGET),netware)
+STATICLIBPREFIX=
+PPUEXT=.ppu
+OEXT=.o
+ASMEXT=.s
+SMARTEXT=.sl
+STATICLIBEXT=.a
+SHAREDLIBEXT=.nlm
+EXEEXT=.nlm
+SHORTSUFFIX=nw
+endif
+ifeq ($(OS_TARGET),netwlibc)
+STATICLIBPREFIX=
+PPUEXT=.ppu
+OEXT=.o
+ASMEXT=.s
+SMARTEXT=.sl
+STATICLIBEXT=.a
+SHAREDLIBEXT=.nlm
+EXEEXT=.nlm
+SHORTSUFFIX=nwl
+endif
+ifeq ($(OS_TARGET),macos)
+BATCHEXT=
+PPUEXT=.ppu
+ASMEXT=.s
+OEXT=.o
+SMARTEXT=.sl
+STATICLIBEXT=.a
+EXEEXT=
+DEBUGSYMEXT=.xcoff
+SHORTSUFFIX=mac
+endif
+endif
+ifneq ($(findstring $(OS_SOURCE),$(LIMIT83fs)),)
+FPCMADE=fpcmade.$(SHORTSUFFIX)
+ZIPSUFFIX=$(SHORTSUFFIX)
+ZIPCROSSPREFIX=
+ZIPSOURCESUFFIX=src
+ZIPEXAMPLESUFFIX=exm
+else
+FPCMADE=fpcmade.$(TARGETSUFFIX)
+ZIPSOURCESUFFIX=.source
+ZIPEXAMPLESUFFIX=.examples
+ifdef CROSSCOMPILE
+ZIPSUFFIX=.$(SOURCESUFFIX)
+ZIPCROSSPREFIX=$(TARGETSUFFIX)-
+else
+ZIPSUFFIX=.$(TARGETSUFFIX)
+ZIPCROSSPREFIX=
+endif
+endif
+ifndef ECHO
+ECHO:=$(strip $(wildcard $(addsuffix /gecho$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(ECHO),)
+ECHO:=$(strip $(wildcard $(addsuffix /echo$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(ECHO),)
+ECHO= __missing_command_ECHO
+else
+ECHO:=$(firstword $(ECHO))
+endif
+else
+ECHO:=$(firstword $(ECHO))
+endif
+endif
+export ECHO
+ifndef DATE
+DATE:=$(strip $(wildcard $(addsuffix /gdate$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(DATE),)
+DATE:=$(strip $(wildcard $(addsuffix /date$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(DATE),)
+DATE= __missing_command_DATE
+else
+DATE:=$(firstword $(DATE))
+endif
+else
+DATE:=$(firstword $(DATE))
+endif
+endif
+export DATE
+ifndef GINSTALL
+GINSTALL:=$(strip $(wildcard $(addsuffix /ginstall$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(GINSTALL),)
+GINSTALL:=$(strip $(wildcard $(addsuffix /install$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(GINSTALL),)
+GINSTALL= __missing_command_GINSTALL
+else
+GINSTALL:=$(firstword $(GINSTALL))
+endif
+else
+GINSTALL:=$(firstword $(GINSTALL))
+endif
+endif
+export GINSTALL
+ifndef CPPROG
+CPPROG:=$(strip $(wildcard $(addsuffix /cp$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(CPPROG),)
+CPPROG= __missing_command_CPPROG
+else
+CPPROG:=$(firstword $(CPPROG))
+endif
+endif
+export CPPROG
+ifndef RMPROG
+RMPROG:=$(strip $(wildcard $(addsuffix /rm$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(RMPROG),)
+RMPROG= __missing_command_RMPROG
+else
+RMPROG:=$(firstword $(RMPROG))
+endif
+endif
+export RMPROG
+ifndef MVPROG
+MVPROG:=$(strip $(wildcard $(addsuffix /mv$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(MVPROG),)
+MVPROG= __missing_command_MVPROG
+else
+MVPROG:=$(firstword $(MVPROG))
+endif
+endif
+export MVPROG
+ifndef MKDIRPROG
+MKDIRPROG:=$(strip $(wildcard $(addsuffix /gmkdir$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(MKDIRPROG),)
+MKDIRPROG:=$(strip $(wildcard $(addsuffix /mkdir$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(MKDIRPROG),)
+MKDIRPROG= __missing_command_MKDIRPROG
+else
+MKDIRPROG:=$(firstword $(MKDIRPROG))
+endif
+else
+MKDIRPROG:=$(firstword $(MKDIRPROG))
+endif
+endif
+export MKDIRPROG
+ifndef ECHOREDIR
+ifndef inUnix
+ECHOREDIR=echo
+else
+ECHOREDIR=$(ECHO)
+endif
+endif
+ifndef COPY
+COPY:=$(CPPROG) -fp
+endif
+ifndef COPYTREE
+COPYTREE:=$(CPPROG) -Rfp
+endif
+ifndef MKDIRTREE
+MKDIRTREE:=$(MKDIRPROG) -p
+endif
+ifndef MOVE
+MOVE:=$(MVPROG) -f
+endif
+ifndef DEL
+DEL:=$(RMPROG) -f
+endif
+ifndef DELTREE
+DELTREE:=$(RMPROG) -rf
+endif
+ifndef INSTALL
+ifdef inUnix
+INSTALL:=$(GINSTALL) -c -m 644
+else
+INSTALL:=$(COPY)
+endif
+endif
+ifndef INSTALLEXE
+ifdef inUnix
+INSTALLEXE:=$(GINSTALL) -c -m 755
+else
+INSTALLEXE:=$(COPY)
+endif
+endif
+ifndef MKDIR
+MKDIR:=$(GINSTALL) -m 755 -d
+endif
+export ECHOREDIR COPY COPYTREE MOVE DEL DELTREE INSTALL INSTALLEXE MKDIR
+ifndef PPUMOVE
+PPUMOVE:=$(strip $(wildcard $(addsuffix /ppumove$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(PPUMOVE),)
+PPUMOVE= __missing_command_PPUMOVE
+else
+PPUMOVE:=$(firstword $(PPUMOVE))
+endif
+endif
+export PPUMOVE
+ifndef FPCMAKE
+FPCMAKE:=$(strip $(wildcard $(addsuffix /fpcmake$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(FPCMAKE),)
+FPCMAKE= __missing_command_FPCMAKE
+else
+FPCMAKE:=$(firstword $(FPCMAKE))
+endif
+endif
+export FPCMAKE
+ifndef ZIPPROG
+ZIPPROG:=$(strip $(wildcard $(addsuffix /zip$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(ZIPPROG),)
+ZIPPROG= __missing_command_ZIPPROG
+else
+ZIPPROG:=$(firstword $(ZIPPROG))
+endif
+endif
+export ZIPPROG
+ifndef TARPROG
+TARPROG:=$(strip $(wildcard $(addsuffix /gtar$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(TARPROG),)
+TARPROG:=$(strip $(wildcard $(addsuffix /tar$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(TARPROG),)
+TARPROG= __missing_command_TARPROG
+else
+TARPROG:=$(firstword $(TARPROG))
+endif
+else
+TARPROG:=$(firstword $(TARPROG))
+endif
+endif
+export TARPROG
+ASNAME=$(BINUTILSPREFIX)as
+LDNAME=$(BINUTILSPREFIX)ld
+ARNAME=$(BINUTILSPREFIX)ar
+RCNAME=$(BINUTILSPREFIX)rc
+ifneq ($(findstring 1.0.,$(FPC_VERSION)),)
+ifeq ($(OS_TARGET),win32)
+ifeq ($(CROSSBINDIR),)
+ASNAME=asw
+LDNAME=ldw
+ARNAME=arw
+endif
+endif
+endif
+ifndef ASPROG
+ifdef CROSSBINDIR
+ASPROG=$(CROSSBINDIR)/$(ASNAME)$(SRCEXEEXT)
+else
+ASPROG=$(ASNAME)
+endif
+endif
+ifndef LDPROG
+ifdef CROSSBINDIR
+LDPROG=$(CROSSBINDIR)/$(LDNAME)$(SRCEXEEXT)
+else
+LDPROG=$(LDNAME)
+endif
+endif
+ifndef RCPROG
+ifdef CROSSBINDIR
+RCPROG=$(CROSSBINDIR)/$(RCNAME)$(SRCEXEEXT)
+else
+RCPROG=$(RCNAME)
+endif
+endif
+ifndef ARPROG
+ifdef CROSSBINDIR
+ARPROG=$(CROSSBINDIR)/$(ARNAME)$(SRCEXEEXT)
+else
+ARPROG=$(ARNAME)
+endif
+endif
+AS=$(ASPROG)
+LD=$(LDPROG)
+RC=$(RCPROG)
+AR=$(ARPROG)
+PPAS=ppas$(SRCBATCHEXT)
+ifdef inUnix
+LDCONFIG=ldconfig
+else
+LDCONFIG=
+endif
+ifdef DATE
+DATESTR:=$(shell $(DATE) +%Y%m%d)
+else
+DATESTR=
+endif
+ifndef UPXPROG
+ifeq ($(OS_TARGET),go32v2)
+UPXPROG:=1
+endif
+ifeq ($(OS_TARGET),win32)
+UPXPROG:=1
+endif
+ifdef UPXPROG
+UPXPROG:=$(strip $(wildcard $(addsuffix /upx$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(UPXPROG),)
+UPXPROG=
+else
+UPXPROG:=$(firstword $(UPXPROG))
+endif
+else
+UPXPROG=
+endif
+endif
+export UPXPROG
+ZIPOPT=-9
+ZIPEXT=.zip
+ifeq ($(USETAR),bz2)
+TAROPT=vj
+TAREXT=.tar.bz2
+else
+TAROPT=vz
+TAREXT=.tar.gz
+endif
+override REQUIRE_PACKAGES=rtl pthreads x11
+ifeq ($(FULL_TARGET),i386-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),i386-go32v2)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),i386-win32)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),i386-os2)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),i386-freebsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),i386-beos)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),i386-netbsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),i386-solaris)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),i386-qnx)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),i386-netware)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),i386-openbsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),i386-wdosx)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),i386-darwin)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),i386-emx)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),i386-watcom)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),i386-netwlibc)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),i386-wince)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),i386-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),i386-symbian)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),m68k-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),m68k-freebsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),m68k-netbsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),m68k-amiga)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),m68k-atari)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),m68k-openbsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),m68k-palmos)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),m68k-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),powerpc-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),powerpc-netbsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),powerpc-amiga)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),powerpc-macos)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),powerpc-darwin)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),powerpc-morphos)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),powerpc-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),sparc-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),sparc-netbsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),sparc-solaris)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),sparc-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),x86_64-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),x86_64-freebsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),x86_64-darwin)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),x86_64-win64)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),x86_64-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),arm-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),arm-palmos)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),arm-wince)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),arm-gba)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),arm-nds)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),arm-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),arm-symbian)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),powerpc64-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),powerpc64-darwin)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifeq ($(FULL_TARGET),powerpc64-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PTHREADS=1
+REQUIRE_PACKAGES_X11=1
+endif
+ifdef REQUIRE_PACKAGES_RTL
+PACKAGEDIR_RTL:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /rtl/Makefile.fpc,$(PACKAGESDIR))))))
+ifneq ($(PACKAGEDIR_RTL),)
+ifneq ($(wildcard $(PACKAGEDIR_RTL)/units/$(TARGETSUFFIX)),)
+UNITDIR_RTL=$(PACKAGEDIR_RTL)/units/$(TARGETSUFFIX)
+else
+UNITDIR_RTL=$(PACKAGEDIR_RTL)
+endif
+ifdef CHECKDEPEND
+$(PACKAGEDIR_RTL)/$(FPCMADE):
+ $(MAKE) -C $(PACKAGEDIR_RTL) $(FPCMADE)
+override ALLDEPENDENCIES+=$(PACKAGEDIR_RTL)/$(FPCMADE)
+endif
+else
+PACKAGEDIR_RTL=
+UNITDIR_RTL:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /rtl/Package.fpc,$(UNITSDIR)))))
+ifneq ($(UNITDIR_RTL),)
+UNITDIR_RTL:=$(firstword $(UNITDIR_RTL))
+else
+UNITDIR_RTL=
+endif
+endif
+ifdef UNITDIR_RTL
+override COMPILER_UNITDIR+=$(UNITDIR_RTL)
+endif
+endif
+ifdef REQUIRE_PACKAGES_PTHREADS
+PACKAGEDIR_PTHREADS:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /pthreads/Makefile.fpc,$(PACKAGESDIR))))))
+ifneq ($(PACKAGEDIR_PTHREADS),)
+ifneq ($(wildcard $(PACKAGEDIR_PTHREADS)/units/$(TARGETSUFFIX)),)
+UNITDIR_PTHREADS=$(PACKAGEDIR_PTHREADS)/units/$(TARGETSUFFIX)
+else
+UNITDIR_PTHREADS=$(PACKAGEDIR_PTHREADS)
+endif
+ifdef CHECKDEPEND
+$(PACKAGEDIR_PTHREADS)/$(FPCMADE):
+ $(MAKE) -C $(PACKAGEDIR_PTHREADS) $(FPCMADE)
+override ALLDEPENDENCIES+=$(PACKAGEDIR_PTHREADS)/$(FPCMADE)
+endif
+else
+PACKAGEDIR_PTHREADS=
+UNITDIR_PTHREADS:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /pthreads/Package.fpc,$(UNITSDIR)))))
+ifneq ($(UNITDIR_PTHREADS),)
+UNITDIR_PTHREADS:=$(firstword $(UNITDIR_PTHREADS))
+else
+UNITDIR_PTHREADS=
+endif
+endif
+ifdef UNITDIR_PTHREADS
+override COMPILER_UNITDIR+=$(UNITDIR_PTHREADS)
+endif
+endif
+ifdef REQUIRE_PACKAGES_X11
+PACKAGEDIR_X11:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /x11/Makefile.fpc,$(PACKAGESDIR))))))
+ifneq ($(PACKAGEDIR_X11),)
+ifneq ($(wildcard $(PACKAGEDIR_X11)/units/$(TARGETSUFFIX)),)
+UNITDIR_X11=$(PACKAGEDIR_X11)/units/$(TARGETSUFFIX)
+else
+UNITDIR_X11=$(PACKAGEDIR_X11)
+endif
+ifdef CHECKDEPEND
+$(PACKAGEDIR_X11)/$(FPCMADE):
+ $(MAKE) -C $(PACKAGEDIR_X11) $(FPCMADE)
+override ALLDEPENDENCIES+=$(PACKAGEDIR_X11)/$(FPCMADE)
+endif
+else
+PACKAGEDIR_X11=
+UNITDIR_X11:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /x11/Package.fpc,$(UNITSDIR)))))
+ifneq ($(UNITDIR_X11),)
+UNITDIR_X11:=$(firstword $(UNITDIR_X11))
+else
+UNITDIR_X11=
+endif
+endif
+ifdef UNITDIR_X11
+override COMPILER_UNITDIR+=$(UNITDIR_X11)
+endif
+endif
+ifndef NOCPUDEF
+override FPCOPTDEF=$(CPU_TARGET)
+endif
+ifneq ($(OS_TARGET),$(OS_SOURCE))
+override FPCOPT+=-T$(OS_TARGET)
+endif
+ifneq ($(CPU_TARGET),$(CPU_SOURCE))
+override FPCOPT+=-P$(CPU_TARGET)
+endif
+ifeq ($(OS_SOURCE),openbsd)
+override FPCOPT+=-FD$(NEW_BINUTILS_PATH)
+endif
+ifndef CROSSBOOTSTRAP
+ifneq ($(BINUTILSPREFIX),)
+override FPCOPT+=-XP$(BINUTILSPREFIX)
+endif
+ifneq ($(BINUTILSPREFIX),)
+override FPCOPT+=-Xr$(RLINKPATH)
+endif
+endif
+ifdef UNITDIR
+override FPCOPT+=$(addprefix -Fu,$(UNITDIR))
+endif
+ifdef LIBDIR
+override FPCOPT+=$(addprefix -Fl,$(LIBDIR))
+endif
+ifdef OBJDIR
+override FPCOPT+=$(addprefix -Fo,$(OBJDIR))
+endif
+ifdef INCDIR
+override FPCOPT+=$(addprefix -Fi,$(INCDIR))
+endif
+ifdef LINKSMART
+override FPCOPT+=-XX
+endif
+ifdef CREATESMART
+override FPCOPT+=-CX
+endif
+ifdef DEBUG
+override FPCOPT+=-gl
+override FPCOPTDEF+=DEBUG
+endif
+ifdef RELEASE
+ifneq ($(findstring 2.0.,$(FPC_VERSION)),)
+ifeq ($(CPU_TARGET),i386)
+FPCCPUOPT:=-OG2p3
+endif
+ifeq ($(CPU_TARGET),powerpc)
+FPCCPUOPT:=-O1r
+endif
+else
+FPCCPUOPT:=-O2
+endif
+override FPCOPT+=-Ur -Xs $(FPCCPUOPT) -n
+override FPCOPTDEF+=RELEASE
+endif
+ifdef STRIP
+override FPCOPT+=-Xs
+endif
+ifdef OPTIMIZE
+override FPCOPT+=-O2
+endif
+ifdef VERBOSE
+override FPCOPT+=-vwni
+endif
+ifdef COMPILER_OPTIONS
+override FPCOPT+=$(COMPILER_OPTIONS)
+endif
+ifdef COMPILER_UNITDIR
+override FPCOPT+=$(addprefix -Fu,$(COMPILER_UNITDIR))
+endif
+ifdef COMPILER_LIBRARYDIR
+override FPCOPT+=$(addprefix -Fl,$(COMPILER_LIBRARYDIR))
+endif
+ifdef COMPILER_OBJECTDIR
+override FPCOPT+=$(addprefix -Fo,$(COMPILER_OBJECTDIR))
+endif
+ifdef COMPILER_INCLUDEDIR
+override FPCOPT+=$(addprefix -Fi,$(COMPILER_INCLUDEDIR))
+endif
+ifdef CROSSBINDIR
+override FPCOPT+=-FD$(CROSSBINDIR)
+endif
+ifdef COMPILER_TARGETDIR
+override FPCOPT+=-FE$(COMPILER_TARGETDIR)
+ifeq ($(COMPILER_TARGETDIR),.)
+override TARGETDIRPREFIX=
+else
+override TARGETDIRPREFIX=$(COMPILER_TARGETDIR)/
+endif
+endif
+ifdef COMPILER_UNITTARGETDIR
+override FPCOPT+=-FU$(COMPILER_UNITTARGETDIR)
+ifeq ($(COMPILER_UNITTARGETDIR),.)
+override UNITTARGETDIRPREFIX=
+else
+override UNITTARGETDIRPREFIX=$(COMPILER_UNITTARGETDIR)/
+endif
+else
+ifdef COMPILER_TARGETDIR
+override COMPILER_UNITTARGETDIR=$(COMPILER_TARGETDIR)
+override UNITTARGETDIRPREFIX=$(TARGETDIRPREFIX)
+endif
+endif
+ifdef CREATESHARED
+override FPCOPT+=-Cg
+ifeq ($(CPU_TARGET),i386)
+override FPCOPT+=-Aas
+endif
+endif
+ifeq ($(findstring 2.0.,$(FPC_VERSION)),)
+ifeq ($(OS_TARGET),linux)
+ifeq ($(CPU_TARGET),x86_64)
+override FPCOPT+=-Cg
+endif
+endif
+endif
+ifdef LINKSHARED
+endif
+ifdef GCCLIBDIR
+override FPCOPT+=-Fl$(GCCLIBDIR)
+endif
+ifdef OTHERLIBDIR
+override FPCOPT+=$(addprefix -Fl,$(OTHERLIBDIR))
+endif
+ifdef OPT
+override FPCOPT+=$(OPT)
+endif
+ifdef FPCOPTDEF
+override FPCOPT+=$(addprefix -d,$(FPCOPTDEF))
+endif
+ifdef CFGFILE
+override FPCOPT+=@$(CFGFILE)
+endif
+ifdef USEENV
+override FPCEXTCMD:=$(FPCOPT)
+override FPCOPT:=!FPCEXTCMD
+export FPCEXTCMD
+endif
+override AFULL_TARGET=$(CPU_TARGET)-$(OS_TARGET)
+override AFULL_SOURCE=$(CPU_SOURCE)-$(OS_SOURCE)
+ifneq ($(AFULL_TARGET),$(AFULL_SOURCE))
+override ACROSSCOMPILE=1
+endif
+ifdef ACROSSCOMPILE
+override FPCOPT+=$(CROSSOPT)
+endif
+override COMPILER:=$(FPC) $(FPCOPT)
+ifeq (,$(findstring -s ,$(COMPILER)))
+EXECPPAS=
+else
+ifeq ($(FULL_SOURCE),$(FULL_TARGET))
+ifdef RUNBATCH
+EXECPPAS:=@$(RUNBATCH) $(PPAS)
+else
+EXECPPAS:=@$(PPAS)
+endif
+endif
+endif
+.PHONY: fpc_units
+ifneq ($(TARGET_UNITS)$(TARGET_IMPLICITUNITS),)
+override ALLTARGET+=fpc_units
+override UNITPPUFILES=$(addsuffix $(PPUEXT),$(TARGET_UNITS))
+override IMPLICITUNITPPUFILES=$(addsuffix $(PPUEXT),$(TARGET_IMPLICITUNITS))
+override INSTALLPPUFILES+=$(UNITPPUFILES) $(IMPLICITUNITPPUFILES)
+override CLEANPPUFILES+=$(UNITPPUFILES) $(IMPLICITUNITPPUFILES)
+endif
+fpc_units: $(COMPILER_UNITTARGETDIR) $(UNITPPUFILES)
+ifdef TARGET_RSTS
+override RSTFILES=$(addsuffix $(RSTEXT),$(TARGET_RSTS))
+override CLEANRSTFILES+=$(RSTFILES)
+endif
+.PHONY: fpc_all fpc_smart fpc_debug fpc_release fpc_shared
+$(FPCMADE): $(ALLDEPENDENCIES) $(ALLTARGET)
+ @$(ECHOREDIR) Compiled > $(FPCMADE)
+fpc_all: $(FPCMADE)
+fpc_smart:
+ $(MAKE) all LINKSMART=1 CREATESMART=1
+fpc_debug:
+ $(MAKE) all DEBUG=1
+fpc_release:
+ $(MAKE) all RELEASE=1
+.SUFFIXES: $(EXEEXT) $(PPUEXT) $(OEXT) .pas .lpr .dpr .pp .rc .res
+$(COMPILER_UNITTARGETDIR):
+ $(MKDIRTREE) $(COMPILER_UNITTARGETDIR)
+$(COMPILER_TARGETDIR):
+ $(MKDIRTREE) $(COMPILER_TARGETDIR)
+%$(PPUEXT): %.pp
+ $(COMPILER) $<
+ $(EXECPPAS)
+%$(PPUEXT): %.pas
+ $(COMPILER) $<
+ $(EXECPPAS)
+%$(EXEEXT): %.pp
+ $(COMPILER) $<
+ $(EXECPPAS)
+%$(EXEEXT): %.pas
+ $(COMPILER) $<
+ $(EXECPPAS)
+%$(EXEEXT): %.lpr
+ $(COMPILER) $<
+ $(EXECPPAS)
+%$(EXEEXT): %.dpr
+ $(COMPILER) $<
+ $(EXECPPAS)
+%.res: %.rc
+ windres -i $< -o $@
+vpath %.pp $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)
+vpath %.pas $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)
+vpath %.lpr $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)
+vpath %.dpr $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)
+vpath %.inc $(COMPILER_INCLUDEDIR)
+vpath %$(OEXT) $(COMPILER_UNITTARGETDIR)
+vpath %$(PPUEXT) $(COMPILER_UNITTARGETDIR)
+.PHONY: fpc_shared
+override INSTALLTARGET+=fpc_shared_install
+ifndef SHARED_LIBVERSION
+SHARED_LIBVERSION=$(FPC_VERSION)
+endif
+ifndef SHARED_LIBNAME
+SHARED_LIBNAME=$(PACKAGE_NAME)
+endif
+ifndef SHARED_FULLNAME
+SHARED_FULLNAME=$(SHAREDLIBPREFIX)$(SHARED_LIBNAME)-$(SHARED_LIBVERSION)$(SHAREDLIBEXT)
+endif
+ifndef SHARED_LIBUNITS
+SHARED_LIBUNITS:=$(TARGET_UNITS) $(TARGET_IMPLICITUNITS)
+override SHARED_LIBUNITS:=$(filter-out $(INSTALL_BUILDUNIT),$(SHARED_LIBUNITS))
+endif
+fpc_shared:
+ifdef HASSHAREDLIB
+ $(MAKE) all CREATESHARED=1 LINKSHARED=1 CREATESMART=1
+ifneq ($(SHARED_BUILD),n)
+ $(PPUMOVE) -q $(SHARED_LIBUNITS) -i$(COMPILER_UNITTARGETDIR) -o$(SHARED_FULLNAME) -d$(COMPILER_UNITTARGETDIR)
+endif
+else
+ @$(ECHO) Shared Libraries not supported
+endif
+fpc_shared_install:
+ifneq ($(SHARED_BUILD),n)
+ifneq ($(SHARED_LIBUNITS),)
+ifneq ($(wildcard $(COMPILER_UNITTARGETDIR)/$(SHARED_FULLNAME)),)
+ $(INSTALL) $(COMPILER_UNITTARGETDIR)/$(SHARED_FULLNAME) $(INSTALL_SHAREDDIR)
+endif
+endif
+endif
+.PHONY: fpc_install fpc_sourceinstall fpc_exampleinstall
+ifdef INSTALL_UNITS
+override INSTALLPPUFILES+=$(addsuffix $(PPUEXT),$(INSTALL_UNITS))
+endif
+ifdef INSTALL_BUILDUNIT
+override INSTALLPPUFILES:=$(filter-out $(INSTALL_BUILDUNIT)$(PPUEXT),$(INSTALLPPUFILES))
+endif
+ifdef INSTALLPPUFILES
+override INSTALLPPULINKFILES:=$(subst $(PPUEXT),$(OEXT),$(INSTALLPPUFILES)) $(addprefix $(STATICLIBPREFIX),$(subst $(PPUEXT),$(STATICLIBEXT),$(INSTALLPPUFILES))) $(addprefix $(IMPORTLIBPREFIX),$(subst $(PPUEXT),$(STATICLIBEXT),$(INSTALLPPUFILES)))
+ifneq ($(UNITTARGETDIRPREFIX),)
+override INSTALLPPUFILES:=$(addprefix $(UNITTARGETDIRPREFIX),$(notdir $(INSTALLPPUFILES)))
+override INSTALLPPULINKFILES:=$(wildcard $(addprefix $(UNITTARGETDIRPREFIX),$(notdir $(INSTALLPPULINKFILES))))
+endif
+override INSTALL_CREATEPACKAGEFPC=1
+endif
+ifdef INSTALLEXEFILES
+ifneq ($(TARGETDIRPREFIX),)
+override INSTALLEXEFILES:=$(addprefix $(TARGETDIRPREFIX),$(notdir $(INSTALLEXEFILES)))
+endif
+endif
+fpc_install: all $(INSTALLTARGET)
+ifdef INSTALLEXEFILES
+ $(MKDIR) $(INSTALL_BINDIR)
+ifdef UPXPROG
+ -$(UPXPROG) $(INSTALLEXEFILES)
+endif
+ $(INSTALLEXE) $(INSTALLEXEFILES) $(INSTALL_BINDIR)
+endif
+ifdef INSTALL_CREATEPACKAGEFPC
+ifdef FPCMAKE
+ifdef PACKAGE_VERSION
+ifneq ($(wildcard Makefile.fpc),)
+ $(FPCMAKE) -p -T$(CPU_TARGET)-$(OS_TARGET) Makefile.fpc
+ $(MKDIR) $(INSTALL_UNITDIR)
+ $(INSTALL) Package.fpc $(INSTALL_UNITDIR)
+endif
+endif
+endif
+endif
+ifdef INSTALLPPUFILES
+ $(MKDIR) $(INSTALL_UNITDIR)
+ $(INSTALL) $(INSTALLPPUFILES) $(INSTALL_UNITDIR)
+ifneq ($(INSTALLPPULINKFILES),)
+ $(INSTALL) $(INSTALLPPULINKFILES) $(INSTALL_UNITDIR)
+endif
+ifneq ($(wildcard $(LIB_FULLNAME)),)
+ $(MKDIR) $(INSTALL_LIBDIR)
+ $(INSTALL) $(LIB_FULLNAME) $(INSTALL_LIBDIR)
+ifdef inUnix
+ ln -sf $(LIB_FULLNAME) $(INSTALL_LIBDIR)/$(LIB_NAME)
+endif
+endif
+endif
+ifdef INSTALL_FILES
+ $(MKDIR) $(INSTALL_DATADIR)
+ $(INSTALL) $(INSTALL_FILES) $(INSTALL_DATADIR)
+endif
+fpc_sourceinstall: distclean
+ $(MKDIR) $(INSTALL_SOURCEDIR)
+ $(COPYTREE) $(BASEDIR)/* $(INSTALL_SOURCEDIR)
+fpc_exampleinstall: $(addsuffix _distclean,$(TARGET_EXAMPLEDIRS))
+ifdef HASEXAMPLES
+ $(MKDIR) $(INSTALL_EXAMPLEDIR)
+endif
+ifdef EXAMPLESOURCEFILES
+ $(COPY) $(EXAMPLESOURCEFILES) $(INSTALL_EXAMPLEDIR)
+endif
+ifdef TARGET_EXAMPLEDIRS
+ $(COPYTREE) $(addsuffix /*,$(TARGET_EXAMPLEDIRS)) $(INSTALL_EXAMPLEDIR)
+endif
+.PHONY: fpc_distinstall
+fpc_distinstall: install exampleinstall
+.PHONY: fpc_zipinstall fpc_zipsourceinstall fpc_zipexampleinstall
+ifndef PACKDIR
+ifndef inUnix
+PACKDIR=$(BASEDIR)/../fpc-pack
+else
+PACKDIR=/tmp/fpc-pack
+endif
+endif
+ifndef ZIPNAME
+ifdef DIST_ZIPNAME
+ZIPNAME=$(DIST_ZIPNAME)
+else
+ZIPNAME=$(PACKAGE_NAME)
+endif
+endif
+ifndef FULLZIPNAME
+FULLZIPNAME=$(ZIPCROSSPREFIX)$(ZIPPREFIX)$(ZIPNAME)$(ZIPSUFFIX)
+endif
+ifndef ZIPTARGET
+ifdef DIST_ZIPTARGET
+ZIPTARGET=DIST_ZIPTARGET
+else
+ZIPTARGET=install
+endif
+endif
+ifndef USEZIP
+ifdef inUnix
+USETAR=1
+endif
+endif
+ifndef inUnix
+USEZIPWRAPPER=1
+endif
+ifdef USEZIPWRAPPER
+ZIPPATHSEP=$(PATHSEP)
+ZIPWRAPPER=$(subst /,$(PATHSEP),$(DIST_DESTDIR)/fpczip$(SRCBATCHEXT))
+else
+ZIPPATHSEP=/
+endif
+ZIPCMD_CDPACK:=cd $(subst /,$(ZIPPATHSEP),$(PACKDIR))
+ZIPCMD_CDBASE:=cd $(subst /,$(ZIPPATHSEP),$(BASEDIR))
+ifdef USETAR
+ZIPDESTFILE:=$(DIST_DESTDIR)/$(FULLZIPNAME)$(TAREXT)
+ZIPCMD_ZIP:=$(TARPROG) cf$(TAROPT) $(ZIPDESTFILE) *
+else
+ZIPDESTFILE:=$(DIST_DESTDIR)/$(FULLZIPNAME)$(ZIPEXT)
+ZIPCMD_ZIP:=$(subst /,$(ZIPPATHSEP),$(ZIPPROG)) -Dr $(ZIPOPT) $(ZIPDESTFILE) *
+endif
+fpc_zipinstall:
+ $(MAKE) $(ZIPTARGET) INSTALL_PREFIX=$(PACKDIR) ZIPINSTALL=1
+ $(MKDIR) $(DIST_DESTDIR)
+ $(DEL) $(ZIPDESTFILE)
+ifdef USEZIPWRAPPER
+ifneq ($(ECHOREDIR),echo)
+ $(ECHOREDIR) -e "$(subst \,\\,$(ZIPCMD_CDPACK))" > $(ZIPWRAPPER)
+ $(ECHOREDIR) -e "$(subst \,\\,$(ZIPCMD_ZIP))" >> $(ZIPWRAPPER)
+ $(ECHOREDIR) -e "$(subst \,\\,$(ZIPCMD_CDBASE))" >> $(ZIPWRAPPER)
+else
+ echo $(ZIPCMD_CDPACK) > $(ZIPWRAPPER)
+ echo $(ZIPCMD_ZIP) >> $(ZIPWRAPPER)
+ echo $(ZIPCMD_CDBASE) >> $(ZIPWRAPPER)
+endif
+ifdef inUnix
+ /bin/sh $(ZIPWRAPPER)
+else
+ifdef RUNBATCH
+ $(RUNBATCH) (ZIPWRAPPER)
+else
+ $(ZIPWRAPPER)
+endif
+endif
+ $(DEL) $(ZIPWRAPPER)
+else
+ $(ZIPCMD_CDPACK) ; $(ZIPCMD_ZIP) ; $(ZIPCMD_CDBASE)
+endif
+ $(DELTREE) $(PACKDIR)
+fpc_zipsourceinstall:
+ $(MAKE) fpc_zipinstall ZIPTARGET=sourceinstall ZIPSUFFIX=$(ZIPSOURCESUFFIX)
+fpc_zipexampleinstall:
+ifdef HASEXAMPLES
+ $(MAKE) fpc_zipinstall ZIPTARGET=exampleinstall ZIPSUFFIX=$(ZIPEXAMPLESUFFIX)
+endif
+fpc_zipdistinstall:
+ $(MAKE) fpc_zipinstall ZIPTARGET=distinstall
+.PHONY: fpc_clean fpc_cleanall fpc_distclean
+ifdef EXEFILES
+override CLEANEXEFILES:=$(addprefix $(TARGETDIRPREFIX),$(CLEANEXEFILES))
+endif
+ifdef CLEAN_UNITS
+override CLEANPPUFILES+=$(addsuffix $(PPUEXT),$(CLEAN_UNITS))
+endif
+ifdef CLEANPPUFILES
+override CLEANPPULINKFILES:=$(subst $(PPUEXT),$(OEXT),$(CLEANPPUFILES)) $(addprefix $(STATICLIBPREFIX),$(subst $(PPUEXT),$(STATICLIBEXT),$(CLEANPPUFILES))) $(addprefix $(IMPORTLIBPREFIX),$(subst $(PPUEXT),$(STATICLIBEXT),$(CLEANPPUFILES)))
+ifdef DEBUGSYMEXT
+override CLEANPPULINKFILES+=$(subst $(PPUEXT),$(DEBUGSYMEXT),$(CLEANPPUFILES))
+endif
+override CLEANPPUFILES:=$(addprefix $(UNITTARGETDIRPREFIX),$(CLEANPPUFILES))
+override CLEANPPULINKFILES:=$(wildcard $(addprefix $(UNITTARGETDIRPREFIX),$(CLEANPPULINKFILES)))
+endif
+fpc_clean: $(CLEANTARGET)
+ifdef CLEANEXEFILES
+ -$(DEL) $(CLEANEXEFILES)
+endif
+ifdef CLEANPPUFILES
+ -$(DEL) $(CLEANPPUFILES)
+endif
+ifneq ($(CLEANPPULINKFILES),)
+ -$(DEL) $(CLEANPPULINKFILES)
+endif
+ifdef CLEANRSTFILES
+ -$(DEL) $(addprefix $(UNITTARGETDIRPREFIX),$(CLEANRSTFILES))
+endif
+ifdef CLEAN_FILES
+ -$(DEL) $(CLEAN_FILES)
+endif
+ifdef LIB_NAME
+ -$(DEL) $(LIB_NAME) $(LIB_FULLNAME)
+endif
+ -$(DEL) $(FPCMADE) Package.fpc $(PPAS) script.res link.res $(FPCEXTFILE) $(REDIRFILE)
+ -$(DEL) *$(ASMEXT) *_ppas$(BATCHEXT)
+fpc_cleanall: $(CLEANTARGET)
+ifdef CLEANEXEFILES
+ -$(DEL) $(CLEANEXEFILES)
+endif
+ifdef COMPILER_UNITTARGETDIR
+ifdef CLEANPPUFILES
+ -$(DEL) $(CLEANPPUFILES)
+endif
+ifneq ($(CLEANPPULINKFILES),)
+ -$(DEL) $(CLEANPPULINKFILES)
+endif
+ifdef CLEANRSTFILES
+ -$(DEL) $(addprefix $(UNITTARGETDIRPREFIX),$(CLEANRSTFILES))
+endif
+endif
+ -$(DELTREE) units
+ -$(DEL) *$(OEXT) *$(PPUEXT) *$(RSTEXT) *$(ASMEXT) *$(STATICLIBEXT) *$(SHAREDLIBEXT) *$(PPLEXT)
+ifneq ($(PPUEXT),.ppu)
+ -$(DEL) *.o *.ppu *.a
+endif
+ -$(DELTREE) *$(SMARTEXT)
+ -$(DEL) fpcmade.* Package.fpc $(PPAS) script.res link.res $(FPCEXTFILE) $(REDIRFILE)
+ -$(DEL) *_ppas$(BATCHEXT)
+ifdef AOUTEXT
+ -$(DEL) *$(AOUTEXT)
+endif
+ifdef DEBUGSYMEXT
+ -$(DEL) *$(DEBUGSYMEXT)
+endif
+fpc_distclean: cleanall
+.PHONY: fpc_baseinfo
+override INFORULES+=fpc_baseinfo
+fpc_baseinfo:
+ @$(ECHO)
+ @$(ECHO) == Package info ==
+ @$(ECHO) Package Name..... $(PACKAGE_NAME)
+ @$(ECHO) Package Version.. $(PACKAGE_VERSION)
+ @$(ECHO)
+ @$(ECHO) == Configuration info ==
+ @$(ECHO)
+ @$(ECHO) FPC.......... $(FPC)
+ @$(ECHO) FPC Version.. $(FPC_VERSION)
+ @$(ECHO) Source CPU... $(CPU_SOURCE)
+ @$(ECHO) Target CPU... $(CPU_TARGET)
+ @$(ECHO) Source OS.... $(OS_SOURCE)
+ @$(ECHO) Target OS.... $(OS_TARGET)
+ @$(ECHO) Full Source.. $(FULL_SOURCE)
+ @$(ECHO) Full Target.. $(FULL_TARGET)
+ @$(ECHO) SourceSuffix. $(SOURCESUFFIX)
+ @$(ECHO) TargetSuffix. $(TARGETSUFFIX)
+ @$(ECHO)
+ @$(ECHO) == Directory info ==
+ @$(ECHO)
+ @$(ECHO) Required pkgs... $(REQUIRE_PACKAGES)
+ @$(ECHO)
+ @$(ECHO) Basedir......... $(BASEDIR)
+ @$(ECHO) FPCDir.......... $(FPCDIR)
+ @$(ECHO) CrossBinDir..... $(CROSSBINDIR)
+ @$(ECHO) UnitsDir........ $(UNITSDIR)
+ @$(ECHO) PackagesDir..... $(PACKAGESDIR)
+ @$(ECHO)
+ @$(ECHO) GCC library..... $(GCCLIBDIR)
+ @$(ECHO) Other library... $(OTHERLIBDIR)
+ @$(ECHO)
+ @$(ECHO) == Tools info ==
+ @$(ECHO)
+ @$(ECHO) As........ $(AS)
+ @$(ECHO) Ld........ $(LD)
+ @$(ECHO) Ar........ $(AR)
+ @$(ECHO) Rc........ $(RC)
+ @$(ECHO)
+ @$(ECHO) Mv........ $(MVPROG)
+ @$(ECHO) Cp........ $(CPPROG)
+ @$(ECHO) Rm........ $(RMPROG)
+ @$(ECHO) GInstall.. $(GINSTALL)
+ @$(ECHO) Echo...... $(ECHO)
+ @$(ECHO) Shell..... $(SHELL)
+ @$(ECHO) Date...... $(DATE)
+ @$(ECHO) FPCMake... $(FPCMAKE)
+ @$(ECHO) PPUMove... $(PPUMOVE)
+ @$(ECHO) Upx....... $(UPXPROG)
+ @$(ECHO) Zip....... $(ZIPPROG)
+ @$(ECHO)
+ @$(ECHO) == Object info ==
+ @$(ECHO)
+ @$(ECHO) Target Loaders........ $(TARGET_LOADERS)
+ @$(ECHO) Target Units.......... $(TARGET_UNITS)
+ @$(ECHO) Target Implicit Units. $(TARGET_IMPLICITUNITS)
+ @$(ECHO) Target Programs....... $(TARGET_PROGRAMS)
+ @$(ECHO) Target Dirs........... $(TARGET_DIRS)
+ @$(ECHO) Target Examples....... $(TARGET_EXAMPLES)
+ @$(ECHO) Target ExampleDirs.... $(TARGET_EXAMPLEDIRS)
+ @$(ECHO)
+ @$(ECHO) Clean Units......... $(CLEAN_UNITS)
+ @$(ECHO) Clean Files......... $(CLEAN_FILES)
+ @$(ECHO)
+ @$(ECHO) Install Units....... $(INSTALL_UNITS)
+ @$(ECHO) Install Files....... $(INSTALL_FILES)
+ @$(ECHO)
+ @$(ECHO) == Install info ==
+ @$(ECHO)
+ @$(ECHO) DateStr.............. $(DATESTR)
+ @$(ECHO) ZipName.............. $(ZIPNAME)
+ @$(ECHO) ZipPrefix............ $(ZIPPREFIX)
+ @$(ECHO) ZipCrossPrefix....... $(ZIPCROSSPREFIX)
+ @$(ECHO) ZipSuffix............ $(ZIPSUFFIX)
+ @$(ECHO) FullZipName.......... $(FULLZIPNAME)
+ @$(ECHO) Install FPC Package.. $(INSTALL_FPCPACKAGE)
+ @$(ECHO)
+ @$(ECHO) Install base dir..... $(INSTALL_BASEDIR)
+ @$(ECHO) Install binary dir... $(INSTALL_BINDIR)
+ @$(ECHO) Install library dir.. $(INSTALL_LIBDIR)
+ @$(ECHO) Install units dir.... $(INSTALL_UNITDIR)
+ @$(ECHO) Install source dir... $(INSTALL_SOURCEDIR)
+ @$(ECHO) Install doc dir...... $(INSTALL_DOCDIR)
+ @$(ECHO) Install example dir.. $(INSTALL_EXAMPLEDIR)
+ @$(ECHO) Install data dir..... $(INSTALL_DATADIR)
+ @$(ECHO)
+ @$(ECHO) Dist destination dir. $(DIST_DESTDIR)
+ @$(ECHO) Dist zip name........ $(DIST_ZIPNAME)
+ @$(ECHO)
+.PHONY: fpc_info
+fpc_info: $(INFORULES)
+.PHONY: fpc_makefile fpc_makefiles fpc_makefile_sub1 fpc_makefile_sub2 \
+ fpc_makefile_dirs
+fpc_makefile:
+ $(FPCMAKE) -w -T$(OS_TARGET) Makefile.fpc
+fpc_makefile_sub1:
+ifdef TARGET_DIRS
+ $(FPCMAKE) -w -T$(OS_TARGET) $(addsuffix /Makefile.fpc,$(TARGET_DIRS))
+endif
+ifdef TARGET_EXAMPLEDIRS
+ $(FPCMAKE) -w -T$(OS_TARGET) $(addsuffix /Makefile.fpc,$(TARGET_EXAMPLEDIRS))
+endif
+fpc_makefile_sub2: $(addsuffix _makefile_dirs,$(TARGET_DIRS) $(TARGET_EXAMPLEDIRS))
+fpc_makefile_dirs: fpc_makefile_sub1 fpc_makefile_sub2
+fpc_makefiles: fpc_makefile fpc_makefile_dirs
+all: fpc_all
+debug: fpc_debug
+smart: fpc_smart
+release: fpc_release
+units: fpc_units
+examples:
+shared: fpc_shared
+install: fpc_install
+sourceinstall: fpc_sourceinstall
+exampleinstall: fpc_exampleinstall
+distinstall: fpc_distinstall
+zipinstall: fpc_zipinstall
+zipsourceinstall: fpc_zipsourceinstall
+zipexampleinstall: fpc_zipexampleinstall
+zipdistinstall: fpc_zipdistinstall
+clean: fpc_clean
+distclean: fpc_distclean
+cleanall: fpc_cleanall
+info: fpc_info
+makefiles: fpc_makefiles
+.PHONY: all debug smart release units examples shared install sourceinstall exampleinstall distinstall zipinstall zipsourceinstall zipexampleinstall zipdistinstall clean distclean cleanall info makefiles
+ifneq ($(wildcard fpcmake.loc),)
+include fpcmake.loc
+endif
+.NOTPARALLEL:
diff --git a/packages/sdl/Makefile.fpc b/packages/sdl/Makefile.fpc
new file mode 100644
index 0000000000..55a9cf6f1f
--- /dev/null
+++ b/packages/sdl/Makefile.fpc
@@ -0,0 +1,33 @@
+#
+# Makefile.fpc for SDL bindings
+#
+
+[package]
+name=sdl
+version=1.0.0
+
+[require]
+libc=y
+packages=pthreads x11
+
+[target]
+units=sdl sdl_image sdl_mixer sdl_mixer_nosmpeg sdl_ttf sdl_gfx sdl_net smpeg logger
+units_i386_linux=sdlutils
+units_powerpc_linux=sdlutils
+units_freebsd_i386=sdlutils
+units_win32=sdlutils
+units_powerpc_darwin=sdlutils
+units_i386_darwin=sdlutils
+
+[install]
+fpcpackage=y
+
+[default]
+fpcdir=../..
+
+[compiler]
+includedir=src
+sourcedir=src tests
+
+[rules]
+.NOTPARALLEL:
diff --git a/packages/sdl/README b/packages/sdl/README
new file mode 100644
index 0000000000..68c5eb7cf6
--- /dev/null
+++ b/packages/sdl/README
@@ -0,0 +1,7 @@
+Taken from project jedi (http://www.delphi-jedi.org/Jedi:TEAM_SDL_HOME) with permission.
+
+Relicensed under LGPLv2 with exception as per LGPL and LGPL.addon with permission. You can use this code as long as you abide by either the LGPL + exception license, or the original MPL-1.1 license.
+
+Currently, only SDL, SDL_Image, SDL_Mixer, SDL_gfx and SDL_ttf are compiled and installed. Additional files will be addes as I'm able to test them.
+
+SDL_mixer_nosmpeg unit was added to provide a "smpeg-less" way to use SDL_mixer if the users don't need mp3 support and don't want to depend on the somewhat rare smpeg.dll/so/dylib. Ofcourse for this to work, you need to have a libSDL setup (eg: the libs themselves) without smpeg compiled in. It's worth the trouble in windows however...
diff --git a/packages/sdl/fpmake.pp b/packages/sdl/fpmake.pp
new file mode 100644
index 0000000000..c3626bcc61
--- /dev/null
+++ b/packages/sdl/fpmake.pp
@@ -0,0 +1,91 @@
+{$ifndef ALLPACKAGES}
+{$mode objfpc}{$H+}
+program fpmake;
+
+uses fpmkunit;
+
+Var
+ P : TPackage;
+ T : TTarget;
+begin
+ With Installer do
+ begin
+{$endif ALLPACKAGES}
+
+ P:=AddPackage('sdl');
+{$ifdef ALLPACKAGES}
+ P.Directory:='sdl';
+{$endif ALLPACKAGES}
+ P.Version:='2.0.0';
+ P.SourcePath.Add('src');
+ P.Dependencies.Add('x11');
+ P.Dependencies.Add('pthreads');
+
+ T:=P.Targets.AddUnit('logger.pas');
+ with T.Dependencies do
+ begin
+ AddInclude('jedi-sdl.inc');
+ end;
+ T:=P.Targets.AddUnit('sdl_gfx.pas');
+ with T.Dependencies do
+ begin
+ AddInclude('jedi-sdl.inc');
+ AddUnit('sdl');
+ end;
+ T:=P.Targets.AddUnit('sdl_image.pas');
+ with T.Dependencies do
+ begin
+ AddInclude('jedi-sdl.inc');
+ AddUnit('sdl');
+ end;
+ T:=P.Targets.AddUnit('sdl_mixer_nosmpeg.pas');
+ with T.Dependencies do
+ begin
+ AddInclude('jedi-sdl.inc');
+ AddUnit('sdl');
+ end;
+ T:=P.Targets.AddUnit('sdl_mixer.pas');
+ with T.Dependencies do
+ begin
+ AddInclude('jedi-sdl.inc');
+ AddUnit('smpeg');
+ AddUnit('sdl');
+ end;
+ T:=P.Targets.AddUnit('sdl_net.pas');
+ with T.Dependencies do
+ begin
+ AddInclude('jedi-sdl.inc');
+ AddUnit('sdl');
+ end;
+ T:=P.Targets.AddUnit('sdl.pas');
+ with T.Dependencies do
+ begin
+ AddInclude('jedi-sdl.inc');
+ AddUnit('pthreads');
+ AddUnit('xlib');
+ end;
+ T:=P.Targets.AddUnit('sdl_ttf.pas');
+ with T.Dependencies do
+ begin
+ AddInclude('jedi-sdl.inc');
+ AddUnit('sdl');
+ end;
+ T:=P.Targets.AddUnit('sdlutils.pas');
+ with T.Dependencies do
+ begin
+ AddInclude('jedi-sdl.inc');
+ AddUnit('xlib');
+ AddUnit('sdl');
+ end;
+ T:=P.Targets.AddUnit('smpeg.pas');
+ with T.Dependencies do
+ begin
+ AddInclude('jedi-sdl.inc');
+ AddUnit('sdl');
+ end;
+
+{$ifndef ALLPACKAGES}
+ Run;
+ end;
+end.
+{$endif ALLPACKAGES}
diff --git a/packages/sdl/src/jedi-sdl.inc b/packages/sdl/src/jedi-sdl.inc
new file mode 100644
index 0000000000..0130ad32cc
--- /dev/null
+++ b/packages/sdl/src/jedi-sdl.inc
@@ -0,0 +1,438 @@
+{
+ $Id: jedi-sdl.inc,v 1.15 2007/05/29 21:30:48 savage Exp $
+}
+{******************************************************************************}
+{ }
+{ Borland Delphi SDL - Simple DirectMedia Layer }
+{ Global Conditional Definitions for JEDI-SDL cross-compilation }
+{ }
+{ }
+{ The initial developer of this Pascal code was : }
+{ Prof. Abimbola Olowofoyeku <http://www.bigfoot.com/~African_Chief/> }
+{ }
+{ Portions created by Prof. Abimbola Olowofoyeku are }
+{ Copyright (C) 2000 - 2100 Prof. Abimbola Olowofoyeku. }
+{ }
+{ }
+{ Contributor(s) }
+{ -------------- }
+{ Prof. Abimbola Olowofoyeku <http://www.bigfoot.com/~African_Chief/> }
+{ Dominqiue Louis <Dominique@SavageSoftware.com.au> }
+{ }
+{ Obtained through: }
+{ Joint Endeavour of Delphi Innovators ( Project JEDI ) }
+{ }
+{ You may retrieve the latest version of this file at the Project }
+{ JEDI home page, located at http://delphi-jedi.org }
+{ }
+{ The contents of this file are used with permission, subject to }
+{ the Mozilla Public License Version 1.1 (the "License"); you may }
+{ not use this file except in compliance with the License. You may }
+{ obtain a copy of the License at }
+{ http://www.mozilla.org/MPL/MPL-1.1.html }
+{ }
+{ Software distributed under the License is distributed on an }
+{ "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or }
+{ implied. See the License for the specific language governing }
+{ rights and limitations under the License. }
+{ }
+{ Description }
+{ ----------- }
+{ This code has been copied from... }
+{ Global Conditional Definitions for Chief's UNZIP package }
+{ By Prof. Abimbola Olowofoyeku (The African Chief) }
+{ http://www.bigfoot.com/~African_Chief/ }
+{ }
+{ }
+{ Requires }
+{ -------- }
+{ The SDL Runtime libraris on Win32 : SDL.dll on Linux : libSDL.so }
+{ They are available from... }
+{ http://www.libsdl.org . }
+{ }
+{ Programming Notes }
+{ ----------------- }
+{ }
+{ }
+{ }
+{ }
+{ Revision History }
+{ ---------------- }
+{ 2003-04-03 DL - Initial addition }
+{ }
+{ 2003-04-07 DL - Added Macro ON derective for FPC and OpenGL and removed }
+{ WEAKPACKAGE derective. WEAKPACKAGE should be set when }
+{ appropriate. }
+{ }
+{ 2003-04-23 - DL : under instruction from Alexey Barkovoy I have added }
+{ better TMT Pascal support and under instruction }
+{ from Prof. Abimbola Olowofoyeku (The African Chief) }
+{ I have added better Gnu Pascal support }
+{ }
+{ 2004-01-19 - DL : Under instruction from Marco van de Voort, I have added }
+{ Better FPC support for FreeBSD. }
+{ }
+(*
+ $Log: jedi-sdl.inc,v $
+ Revision 1.15 2007/05/29 21:30:48 savage
+ Changes as suggested by Almindor for 64bit compatibility.
+
+ Revision 1.14 2007/05/20 20:29:11 savage
+ Initial Changes to Handle 64 Bits
+
+ Revision 1.13 2007/01/21 15:51:45 savage
+ Added Delphi 2006 support
+
+ Revision 1.12 2006/11/19 18:41:01 savage
+ removed THREADING ON flag as it is no longer needed in latest versions of FPC.
+
+ Revision 1.11 2006/01/04 00:52:41 drellis
+ Updated to include defined for ENDIAN values, SDL_BYTEORDER should now be correctly defined depending onthe platform. Code taken from sdl_mixer
+
+ Revision 1.10 2005/05/22 18:42:31 savage
+ Changes as suggested by Michalis Kamburelis. Thanks again.
+
+ Revision 1.9 2004/12/23 23:42:17 savage
+ Applied Patches supplied by Michalis Kamburelis ( THANKS! ), for greater FreePascal compatability.
+
+ Revision 1.8 2004/10/20 22:43:04 savage
+ Ensure that UNSAFE type warning are off in D9 as well
+
+ Revision 1.7 2004/04/05 09:59:51 savage
+ Changes for FreePacal as suggested by Marco
+
+ Revision 1.6 2004/03/31 22:18:15 savage
+ Small comment for turning off warning under GnuPascal
+
+ Revision 1.5 2004/03/30 22:41:02 savage
+ Added extra commenting due to previous compiler directive
+
+ Revision 1.4 2004/03/30 22:08:33 savage
+ Added Kylix Define
+
+ Revision 1.3 2004/03/30 21:34:40 savage
+ {$H+} needed for FPC compatiblity
+
+ Revision 1.2 2004/02/14 00:23:39 savage
+ As UNIX is defined in jedi-sdl.inc this will be used to check linux compatability as well. Units have been changed to reflect this change.
+
+*)
+{******************************************************************************}
+
+{.$define Debug} { uncomment for debugging }
+
+{$IFNDEF FPC}
+ {$IFDEF __GPC__}
+ {$I-}
+ {$W-} // turn off GPC warnings
+ {$X+}
+ {$ELSE} {__GPC__}
+ {$IFDEF Debug}
+ {$F+,D+,Q-,L+,R+,I-,S+,Y+,A+}
+ {$ELSE}
+ {$F+,Q-,R-,S-,I-,A+}
+ {$ENDIF}
+ {$ENDIF} {__GPC__}
+{$ELSE} {FPC}
+ //{$M+}
+{$ENDIF} {FPC}
+
+{$IFDEF LINUX}
+{$DEFINE UNIX}
+{$ENDIF}
+
+{$IFDEF ver70}
+ {$IFDEF Windows}
+ {$DEFINE Win16}
+ {$ENDIF Windows}
+ {$IFDEF MSDOS}
+ {$DEFINE NO_EXPORTS}
+ {$ENDIF MSDOS}
+ {$IFDEF DPMI}
+ {$DEFINE BP_DPMI}
+ {$ENDIF}
+ {$DEFINE OS_16_BIT}
+ {$DEFINE __OS_DOS__}
+{$ENDIF ver70}
+
+{$IFDEF ver80}
+ {$DEFINE Delphi} {Delphi 1.x}
+ {$DEFINE Delphi16}
+ {$DEFINE Win16}
+ {$DEFINE OS_16_BIT}
+ {$DEFINE __OS_DOS__}
+{$ENDIF ver80}
+
+{$IFDEF ver90}
+ {$DEFINE Delphi} {Delphi 2.x}
+ {$DEFINE Delphi32}
+ {$DEFINE WIN32}
+ {$DEFINE WINDOWS}
+{$ENDIF ver90}
+
+{$IFDEF ver100}
+ {$DEFINE Delphi} {Delphi 3.x}
+ {$DEFINE Delphi32}
+ {$DEFINE WIN32}
+ {$DEFINE WINDOWS}
+{$ENDIF ver100}
+
+{$IFDEF ver93}
+ {$DEFINE Delphi} {C++ Builder 1.x}
+ {$DEFINE Delphi32}
+ {$DEFINE WINDOWS}
+{$ENDIF ver93}
+
+{$IFDEF ver110}
+ {$DEFINE Delphi} {C++ Builder 3.x}
+ {$DEFINE Delphi32}
+ {$DEFINE WINDOWS}
+{$ENDIF ver110}
+
+{$IFDEF ver120}
+ {$DEFINE Delphi} {Delphi 4.x}
+ {$DEFINE Delphi32}
+ {$DEFINE Delphi4UP}
+ {$DEFINE Has_Int64}
+ {$DEFINE WINDOWS}
+{$ENDIF ver120}
+
+{$IFDEF ver130}
+ {$DEFINE Delphi} {Delphi 5.x}
+ {$DEFINE Delphi32}
+ {$DEFINE Delphi4UP}
+ {$DEFINE Delphi5UP}
+ {$DEFINE Has_Int64}
+ {$DEFINE WINDOWS}
+{$ENDIF ver130}
+
+{$IFDEF ver140}
+ {$DEFINE Delphi} {Delphi 6.x}
+ {$DEFINE Delphi32}
+ {$DEFINE Delphi4UP}
+ {$DEFINE Delphi5UP}
+ {$DEFINE Delphi6UP}
+ {$DEFINE Has_Int64}
+ {$DEFINE HAS_TYPES}
+{$ENDIF ver140}
+
+{$IFDEF ver150}
+ {$DEFINE Delphi} {Delphi 7.x}
+ {$DEFINE Delphi32}
+ {$DEFINE Delphi4UP}
+ {$DEFINE Delphi5UP}
+ {$DEFINE Delphi6UP}
+ {$DEFINE Delphi7UP}
+ {$WARN UNSAFE_TYPE OFF} {Disable warning for unsafe types in Delphi 7}
+ {$DEFINE Has_Int64}
+ {$DEFINE HAS_TYPES}
+{$ENDIF ver150}
+
+{$IFDEF ver160}
+ {$DEFINE Delphi} {Delphi 8}
+ {$DEFINE Delphi32}
+ {$DEFINE Delphi4UP}
+ {$DEFINE Delphi5UP}
+ {$DEFINE Delphi6UP}
+ {$DEFINE Delphi7UP}
+ {$DEFINE Delphi8UP}
+ {$DEFINE Has_Int64}
+ {$DEFINE HAS_TYPES}
+{$ENDIF ver160}
+
+{$IFDEF ver170}
+ {$DEFINE Delphi} {Delphi 2005}
+ {$DEFINE Delphi32}
+ {$DEFINE Delphi4UP}
+ {$DEFINE Delphi5UP}
+ {$DEFINE Delphi6UP}
+ {$DEFINE Delphi7UP}
+ {$DEFINE Delphi8UP}
+ {$DEFINE Delphi9UP}
+ {$WARN UNSAFE_TYPE OFF} {Disable warning for unsafe types in Delphi 7}
+ {$DEFINE Has_Int64}
+ {$DEFINE HAS_TYPES}
+{$ENDIF ver170}
+
+{$IFDEF ver180}
+ {$DEFINE Delphi} {Delphi 2006}
+ {$DEFINE Delphi32}
+ {$DEFINE Delphi4UP}
+ {$DEFINE Delphi5UP}
+ {$DEFINE Delphi6UP}
+ {$DEFINE Delphi7UP}
+ {$DEFINE Delphi8UP}
+ {$DEFINE Delphi9UP}
+ {$DEFINE Delphi10UP}
+ {$WARN UNSAFE_TYPE OFF} {Disable warning for unsafe types in Delphi 7}
+ {$DEFINE Has_Int64}
+ {$DEFINE HAS_TYPES}
+{$ENDIF ver180}
+
+{$IFDEF ver185}
+ {$DEFINE Delphi} {Delphi 2007}
+ {$DEFINE Delphi32}
+ {$DEFINE Delphi4UP}
+ {$DEFINE Delphi5UP}
+ {$DEFINE Delphi6UP}
+ {$DEFINE Delphi7UP}
+ {$DEFINE Delphi8UP}
+ {$DEFINE Delphi9UP}
+ {$DEFINE Delphi10UP}
+ {$WARN UNSAFE_TYPE OFF} {Disable warning for unsafe types in Delphi 7}
+ {$DEFINE Has_Int64}
+ {$DEFINE HAS_TYPES}
+{$ENDIF ver180}
+
+{$IFDEF UNIX}
+ {$ifdef VER140} // Kylix 1 & 2
+ {$DEFINE KYLIX}
+ {$DEFINE KYLIX1UP}
+ {$DEFINE KYLIX2UP}
+ {$DEFINE HAS_TYPES}
+ {$endif}
+
+ {$ifdef VER150} // Kylix 3
+ {$DEFINE KYLIX}
+ {$DEFINE KYLIX1UP}
+ {$DEFINE KYLIX2UP}
+ {$DEFINE KYLIX3UP}
+ {$DEFINE HAS_TYPES}
+ {$endif}
+{$ENDIF UNIX}
+
+{$IFDEF VirtualPascal} { Virtual Pascal 2.x }
+ {$DEFINE Delphi} { Use Delphi Syntax }
+ {$DEFINE VP2}
+ {&Delphi+}
+{$ENDIF VirtualPascal}
+
+{$IFDEF Delphi}
+ {$DEFINE Windows}
+ {$DEFINE USE_STDCALL}
+ //{$ALIGN ON}
+{$ENDIF Delphi}
+
+{$IFDEF FPC}
+ {$MODE Delphi} { use Delphi compatibility mode }
+ {$H+}
+ {$PACKRECORDS C} // Added for record
+ {$MACRO ON} // Added For OpenGL
+ {$DEFINE Delphi}
+ {$DEFINE UseAT}
+ {$UNDEF USE_STDCALL}
+ {$DEFINE OS_BigMem}
+ {$DEFINE NO_EXPORTS}
+ {$DEFINE Has_Int64}
+ {$DEFINE NOCRT}
+ {$IFDEF UNIX}
+ {$DEFINE fpc_unix}
+ {$ELSE}
+ {$DEFINE __OS_DOS__}
+ {$ENDIF}
+ {$IFDEF WIN32}
+ {$DEFINE UseWin}
+ {$ENDIF}
+ {$DEFINE HAS_TYPES}
+{$ENDIF FPC}
+
+{$IFDEF Win16}
+ {$K+} {smart callbacks}
+{$ENDIF Win16}
+
+ {$IFDEF OS2}
+ {$UNDEF Windows}
+ {$DEFINE UseWin}
+ {$DEFINE OS_BigMem}
+ {$ENDIF OS2}
+
+{$IFDEF __GPC__}
+ {$UNDEF UseWin}
+ {$UNDEF USE_STDCALL}
+ {$DEFINE OS_BigMem}
+ {$DEFINE NO_EXPORTS}
+ {$DEFINE NOCRT}
+ {$DEFINE cdecl attribute(cdecl)}
+{$ENDIF}
+
+{$IFDEF __TMT__}
+ {$DEFINE OS_BigMem}
+ {$DEFINE NO_EXPORTS}
+ {$DEFINE __OS_DOS__}
+ {$DEFINE UseAT}
+ {$IFNDEF MSDOS}
+ {$DEFINE USE_STDCALL}
+ {$ENDIF}
+
+ {$IFDEF __WIN32__}
+ {$DEFINE Win32}
+ {$DEFINE UseWin}
+ {$DEFINE NOCRT}
+ {$DEFINE Win32}
+ {$IFNDEF __CON__}
+ {$DEFINE Windows}
+ {$ENDIF}
+ {$ENDIF}
+
+ {$A+} // Word alignment data
+ {$OA+} // Objects and structures align
+{$ENDIF}
+
+{$IFDEF Win32}
+ {$DEFINE OS_BigMem}
+{$ELSE Win32}
+ {$IFDEF ver70}
+ {$DEFINE assembler}
+ {$ENDIF} { use 16-bit assembler! }
+{$ENDIF Win32}
+
+{ ************************** dos/dos-like platforms **************}
+{$IFDEF Windows}
+ {$DEFINE __OS_DOS__}
+ {$DEFINE UseWin}
+ {$DEFINE MSWINDOWS}
+{$ENDIF Delphi}
+
+{$IFDEF OS2}
+ {$DEFINE __OS_DOS__}
+ {$DEFINE Can_Use_DLL}
+{$ENDIF Delphi}
+
+{$IFDEF UseWin}
+ {$DEFINE Can_Use_DLL}
+{$ENDIF}
+
+{$IFDEF Win16}
+ {$DEFINE Can_Use_DLL}
+{$ENDIF}
+
+{$IFDEF BP_DPMI}
+ {$DEFINE Can_Use_DLL}
+{$ENDIF}
+
+{$IFDEF USE_STDCALL}
+ {$IFNDEF __TMT__}
+ {$DEFINE BY_NAME}
+ {$ENDIF}
+{$ENDIF}
+
+{$IFNDEF ver70}
+ {$UNDEF assembler}
+{$ENDIF}
+
+{*************** define LITTLE ENDIAN platforms ********************}
+
+
+{$IFDEF Delphi}
+{$DEFINE IA32}
+{$ENDIF}
+
+{$IFDEF KYLIX}
+{$DEFINE IA32}
+{$ENDIF}
+
+{$IFDEF FPC}
+{$IFDEF FPC_LITTLE_ENDIAN}
+{$DEFINE IA32}
+{$ENDIF}
+{$ENDIF}
diff --git a/packages/sdl/src/libxmlparser.pas b/packages/sdl/src/libxmlparser.pas
new file mode 100644
index 0000000000..63e7b7fb53
--- /dev/null
+++ b/packages/sdl/src/libxmlparser.pas
@@ -0,0 +1,2688 @@
+(**
+===============================================================================================
+Name : LibXmlParser
+===============================================================================================
+Project : All Projects
+===============================================================================================
+Subject : Progressive XML Parser for all types of XML Files
+===============================================================================================
+Author : Stefan Heymann
+ Eschenweg 3
+ 72076 Tübingen
+ GERMANY
+
+E-Mail: stefan@destructor.de
+URL: www.destructor.de
+===============================================================================================
+Source, Legals ("Licence")
+--------------------------
+The official site to get this parser is http://www.destructor.de/
+
+Usage and Distribution of this Source Code is ruled by the
+"Destructor.de Source code Licence" (DSL) which comes with this file or
+can be downloaded at http://www.destructor.de/
+
+IN SHORT: Usage and distribution of this source code is free.
+ You use it completely on your own risk.
+
+Postcardware
+------------
+If you like this code, please send a postcard of your city to my above address.
+===============================================================================================
+!!! All parts of this code which are not finished or not conforming exactly to
+ the XmlSpec are marked with three exclamation marks
+
+-!- Parts where the parser may be able to detect errors in the document's syntax are
+ marked with the dash-exlamation mark-dash sequence.
+===============================================================================================
+Terminology:
+------------
+- Start: Start of a buffer part
+- Final: End (last character) of a buffer part
+- DTD: Document Type Definition
+- DTDc: Document Type Declaration
+- XMLSpec: The current W3C XML Recommendation (version 1.0 as of 1998-02-10), Chapter No.
+- Cur*: Fields concerning the "Current" part passed back by the "Scan" method
+===============================================================================================
+Scanning the XML document
+-------------------------
+- Create TXmlParser Instance MyXml := TXmlParser.Create;
+- Load XML Document MyXml.LoadFromFile (Filename);
+- Start Scanning MyXml.StartScan;
+- Scan Loop WHILE MyXml.Scan DO
+- Test for Part Type CASE MyXml.CurPartType OF
+- Handle Parts ... : ;;;
+- Handle Parts ... : ;;;
+- Handle Parts ... : ;;;
+ END;
+- Destroy MyXml.Free;
+===============================================================================================
+Loading the XML document
+------------------------
+You can load the XML document from a file with the "LoadFromFile" method.
+It is beyond the scope of this parser to perform HTTP or FTP accesses. If you want your
+application to handle such requests (URLs), you can load the XML via HTTP or FTP or whatever
+protocol and hand over the data buffer using the "LoadFromBuffer" or "SetBuffer" method.
+"LoadFromBuffer" loads the internal buffer of TXmlParser with the given null-terminated
+string, thereby creating a copy of that buffer.
+"SetBuffer" just takes the pointer to another buffer, which means that the given
+buffer pointer must be valid while the document is accessed via TXmlParser.
+===============================================================================================
+Encodings:
+----------
+This XML parser kind of "understands" the following encodings:
+- UTF-8
+- ISO-8859-1
+- Windows-1252
+
+Any flavor of multi-byte characters (and this includes UTF-16) is not supported. Sorry.
+
+Every string which has to be passed to the application passes the virtual method
+"TranslateEncoding" which translates the string from the current encoding (stored in
+"CurEncoding") into the encoding the application wishes to receive.
+The "TranslateEncoding" method that is built into TXmlParser assumes that the application
+wants to receive Windows ANSI (Windows-1252, about the same as ISO-8859-1) and is able
+to convert UTF-8 and ISO-8859-1 encodings.
+For other source and target encodings, you will have to override "TranslateEncoding".
+===============================================================================================
+Buffer Handling
+---------------
+- The document must be loaded completely into a piece of RAM
+- All character positions are referenced by PChar pointers
+- The TXmlParser instance can either "own" the buffer itself (then, FBufferSize is > 0)
+ or reference the buffer of another instance or object (then, FBuffersize is 0 and
+ FBuffer is not NIL)
+- The Property DocBuffer passes back a pointer to the first byte of the document. If there
+ is no document stored (FBuffer is NIL), the DocBuffer returns a pointer to a NULL character.
+===============================================================================================
+Whitespace Handling
+-------------------
+The TXmlParser property "PackSpaces" determines how Whitespace is returned in Text Content:
+While PackSpaces is true, all leading and trailing whitespace characters are trimmed of, all
+Whitespace is converted to Space #x20 characters and contiguous Whitespace characters are
+compressed to one.
+If the "Scan" method reports a ptContent part, the application can get the original text
+with all whitespace characters by extracting the characters from "CurStart" to "CurFinal".
+If the application detects an xml:space attribute, it can set "PackSpaces" accordingly or
+use CurStart/CurFinal.
+Please note that TXmlParser does _not_ normalize Line Breaks to single LineFeed characters
+as the XmlSpec requires (XmlSpec 2.11).
+The xml:space attribute is not handled by TXmlParser. This is on behalf of the application.
+===============================================================================================
+Non-XML-Conforming
+------------------
+TXmlParser does not conform 100 % exactly to the XmlSpec:
+- UTF-16 is not supported (XmlSpec 2.2)
+ (Workaround: Convert UTF-16 to UTF-8 and hand the buffer over to TXmlParser)
+- As the parser only works with single byte strings, all Unicode characters > 255
+ can currently not be handled correctly.
+- Line breaks are not normalized to single Linefeed #x0A characters (XmlSpec 2.11)
+ (Workaround: The Application can access the text contents on its own [CurStart, CurFinal],
+ thereby applying every normalization it wishes to)
+- The attribute value normalization does not work exactly as defined in the
+ Second Edition of the XML 1.0 specification.
+- See also the code parts marked with three consecutive exclamation marks. These are
+ parts which are not finished in the current code release.
+
+This list may be incomplete, so it may grow if I get to know any other points.
+As work on the parser proceeds, this list may also shrink.
+===============================================================================================
+Things Todo
+-----------
+- Introduce a new event/callback which is called when there is an unresolvable
+ entity or character reference
+- Support Unicode
+- Use Streams instead of reading the whole XML into memory
+===============================================================================================
+Change History, Version numbers
+-------------------------------
+The Date is given in ISO Year-Month-Day (YYYY-MM-DD) order.
+Versions are counted from 1.0.0 beginning with the version from 2000-03-16.
+Unreleased versions don't get a version number.
+
+Date Author Version Changes
+-----------------------------------------------------------------------------------------------
+2000-03-16 HeySt 1.0.0 Start
+2000-03-28 HeySt 1.0.1 Initial Publishing of TXmlParser on the destructor.de Web Site
+2000-03-30 HeySt 1.0.2 TXmlParser.AnalyzeCData: Call "TranslateEncoding" for CurContent
+2000-03-31 HeySt 1.0.3 Deleted the StrPosE function (was not needed anyway)
+2000-04-04 HeySt 1.0.4 TDtdElementRec modified: Start/Final for all Elements;
+ Should be backwards compatible.
+ AnalyzeDtdc: Set CurPartType to ptDtdc
+2000-04-23 HeySt 1.0.5 New class TObjectList. Eliminated reference to the Delphi 5
+ "Contnrs" unit so LibXmlParser is Delphi 4 compatible.
+2000-07-03 HeySt 1.0.6 TNvpNode: Added Constructor
+2000-07-11 HeySt 1.0.7 Removed "Windows" from USES clause
+ Added three-exclamation-mark comments for Utf8ToAnsi/AnsiToUtf8
+ Added three-exclamation-mark comments for CHR function calls
+2000-07-23 HeySt 1.0.8 TXmlParser.Clear: CurAttr.Clear; EntityStack.Clear;
+ (This was not a bug; just defensive programming)
+2000-07-29 HeySt 1.0.9 TNvpList: Added methods: Node(Index), Value(Index), Name(Index);
+2000-10-07 HeySt Introduced Conditional Defines
+ Uses Contnrs unit and its TObjectList class again for
+ Delphi 5 and newer versions
+2001-01-30 HeySt Introduced Version Numbering
+ Made LoadFromFile and LoadFromBuffer BOOLEAN functions
+ Introduced FileMode parameter for LoadFromFile
+ BugFix: TAttrList.Analyze: Must add CWhitespace to ExtractName call
+ Comments worked over
+2001-02-28 HeySt 1.0.10 Completely worked over and tested the UTF-8 functions
+ Fixed a bug in TXmlParser.Scan which caused it to start over when it
+ was called after the end of scanning, resulting in an endless loop
+ TEntityStack is now a TObjectList instead of TList
+2001-07-03 HeySt 1.0.11 Updated Compiler Version IFDEFs for Kylix
+2001-07-11 HeySt 1.0.12 New TCustomXmlScanner component (taken over from LibXmlComps.pas)
+2001-07-14 HeySt 1.0.13 Bugfix TCustomXmlScanner.FOnTranslateEncoding
+2001-10-22 HeySt Don't clear CurName anymore when the parser finds a CDATA section.
+2001-12-03 HeySt 1.0.14 TObjectList.Clear: Make call to INHERITED method (fixes a memory leak)
+2001-12-05 HeySt 1.0.15 TObjectList.Clear: removed call to INHERITED method
+ TObjectList.Destroy: Inserted SetCapacity call.
+ Reduces need for frequent re-allocation of pointer buffer
+ Dedicated to my father, Theodor Heymann
+2002-06-26 HeySt 1.0.16 TXmlParser.Scan: Fixed a bug with PIs whose name is beginning
+ with 'xml'. Thanks to Uwe Kamm for submitting this bug.
+ The CurEncoding property is now always in uppercase letters (the XML
+ spec wants it to be treated case independently so when it's uppercase
+ comparisons are faster)
+2002-03-04 HeySt 1.0.17 Included an IFDEF for Delphi 7 (VER150) and Kylix
+ There is a new symbol HAS_CONTNRS_UNIT which is used now to
+ distinguish between IDEs which come with the Contnrs unit and
+ those that don't.
+*)
+
+UNIT libxmlparser;
+
+{$I jedi-sdl.inc}
+
+INTERFACE
+
+USES
+ SysUtils, Classes,
+ (*$IFDEF HAS_CONTNRS_UNIT *) // The Contnrs Unit was introduced in Delphi 5
+ Contnrs,
+ (*$ENDIF*)
+ Math;
+
+CONST
+ CVersion = '1.0.17'; // This variable will be updated for every release
+ // (I hope, I won't forget to do it everytime ...)
+
+TYPE
+ TPartType = // --- Document Part Types
+ (ptNone, // Nothing
+ ptXmlProlog, // XML Prolog XmlSpec 2.8 / 4.3.1
+ ptComment, // Comment XmlSpec 2.5
+ ptPI, // Processing Instruction XmlSpec 2.6
+ ptDtdc, // Document Type Declaration XmlSpec 2.8
+ ptStartTag, // Start Tag XmlSpec 3.1
+ ptEmptyTag, // Empty-Element Tag XmlSpec 3.1
+ ptEndTag, // End Tag XmlSpec 3.1
+ ptContent, // Text Content between Tags
+ ptCData); // CDATA Section XmlSpec 2.7
+
+ TDtdElemType = // --- DTD Elements
+ (deElement, // !ELEMENT declaration
+ deAttList, // !ATTLIST declaration
+ deEntity, // !ENTITY declaration
+ deNotation, // !NOTATION declaration
+ dePI, // PI in DTD
+ deComment, // Comment in DTD
+ deError); // Error found in the DTD
+
+TYPE
+ TAttrList = CLASS;
+ TEntityStack = CLASS;
+ TNvpList = CLASS;
+ TElemDef = CLASS;
+ TElemList = CLASS;
+ TEntityDef = CLASS;
+ TNotationDef = CLASS;
+
+ TDtdElementRec = RECORD // --- This Record is returned by the DTD parser callback function
+ Start, Final : PChar; // Start/End of the Element's Declaration
+ CASE ElementType : TDtdElemType OF // Type of the Element
+ deElement, // <!ELEMENT>
+ deAttList : (ElemDef : TElemDef); // <!ATTLIST>
+ deEntity : (EntityDef : TEntityDef); // <!ENTITY>
+ deNotation : (NotationDef : TNotationDef); // <!NOTATION>
+ dePI : (Target : PChar; // <?PI ?>
+ Content : PChar;
+ AttrList : TAttrList);
+ deError : (Pos : PChar); // Error
+ // deComment : ((No additional fields here)); // <!-- Comment -->
+ END;
+
+ TXmlParser = CLASS // --- Internal Properties and Methods
+ PROTECTED
+ FBuffer : PChar; // NIL if there is no buffer available
+ FBufferSize : INTEGER; // 0 if the buffer is not owned by the Document instance
+ FSource : STRING; // Name of Source of document. Filename for Documents loaded with LoadFromFile
+
+ FXmlVersion : STRING; // XML version from Document header. Default is '1.0'
+ FEncoding : STRING; // Encoding from Document header. Default is 'UTF-8'
+ FStandalone : BOOLEAN; // Standalone declaration from Document header. Default is 'yes'
+ FRootName : STRING; // Name of the Root Element (= DTD name)
+ FDtdcFinal : PChar; // Pointer to the '>' character terminating the DTD declaration
+
+ FNormalize : BOOLEAN; // If true: Pack Whitespace and don't return empty contents
+ EntityStack : TEntityStack; // Entity Stack for Parameter and General Entities
+ FCurEncoding : STRING; // Current Encoding during parsing (always uppercase)
+
+ PROCEDURE AnalyzeProlog; // Analyze XML Prolog or Text Declaration
+ PROCEDURE AnalyzeComment (Start : PChar; VAR Final : PChar); // Analyze Comments
+ PROCEDURE AnalyzePI (Start : PChar; VAR Final : PChar); // Analyze Processing Instructions (PI)
+ PROCEDURE AnalyzeDtdc; // Analyze Document Type Declaration
+ PROCEDURE AnalyzeDtdElements (Start : PChar; VAR Final : PChar); // Analyze DTD declarations
+ PROCEDURE AnalyzeTag; // Analyze Start/End/Empty-Element Tags
+ PROCEDURE AnalyzeCData; // Analyze CDATA Sections
+ PROCEDURE AnalyzeText (VAR IsDone : BOOLEAN); // Analyze Text Content between Tags
+ PROCEDURE AnalyzeElementDecl (Start : PChar; VAR Final : PChar);
+ PROCEDURE AnalyzeAttListDecl (Start : PChar; VAR Final : PChar);
+ PROCEDURE AnalyzeEntityDecl (Start : PChar; VAR Final : PChar);
+ PROCEDURE AnalyzeNotationDecl (Start : PChar; VAR Final : PChar);
+
+ PROCEDURE PushPE (VAR Start : PChar);
+ PROCEDURE ReplaceCharacterEntities (VAR Str : STRING);
+ PROCEDURE ReplaceParameterEntities (VAR Str : STRING);
+ PROCEDURE ReplaceGeneralEntities (VAR Str : STRING);
+
+ FUNCTION GetDocBuffer : PChar; // Returns FBuffer or a pointer to a NUL char if Buffer is empty
+
+ PUBLIC // --- Document Properties
+ PROPERTY XmlVersion : STRING READ FXmlVersion; // XML version from the Document Prolog
+ PROPERTY Encoding : STRING READ FEncoding; // Document Encoding from Prolog
+ PROPERTY Standalone : BOOLEAN READ FStandalone; // Standalone Declaration from Prolog
+ PROPERTY RootName : STRING READ FRootName; // Name of the Root Element
+ PROPERTY Normalize : BOOLEAN READ FNormalize WRITE FNormalize; // True if Content is to be normalized
+ PROPERTY Source : STRING READ FSource; // Name of Document Source (Filename)
+ PROPERTY DocBuffer : PChar READ GetDocBuffer; // Returns document buffer
+ PUBLIC // --- DTD Objects
+ Elements : TElemList; // Elements: List of TElemDef (contains Attribute Definitions)
+ Entities : TNvpList; // General Entities: List of TEntityDef
+ ParEntities : TNvpList; // Parameter Entities: List of TEntityDef
+ Notations : TNvpList; // Notations: List of TNotationDef
+ PUBLIC
+ CONSTRUCTOR Create;
+ DESTRUCTOR Destroy; OVERRIDE;
+
+ // --- Document Handling
+ FUNCTION LoadFromFile (Filename : STRING;
+ FileMode : INTEGER = fmOpenRead OR fmShareDenyNone) : BOOLEAN;
+ // Loads Document from given file
+ FUNCTION LoadFromBuffer (Buffer : PChar) : BOOLEAN; // Loads Document from another buffer
+ PROCEDURE SetBuffer (Buffer : PChar); // References another buffer
+ PROCEDURE Clear; // Clear Document
+
+ PUBLIC
+ // --- Scanning through the document
+ CurPartType : TPartType; // Current Type
+ CurName : STRING; // Current Name
+ CurContent : STRING; // Current Normalized Content
+ CurStart : PChar; // Current First character
+ CurFinal : PChar; // Current Last character
+ CurAttr : TAttrList; // Current Attribute List
+ PROPERTY CurEncoding : STRING READ FCurEncoding; // Current Encoding
+ PROCEDURE StartScan;
+ FUNCTION Scan : BOOLEAN;
+
+ // --- Events / Callbacks
+ FUNCTION LoadExternalEntity (SystemId, PublicId,
+ Notation : STRING) : TXmlParser; VIRTUAL;
+ FUNCTION TranslateEncoding (CONST Source : STRING) : STRING; VIRTUAL;
+ PROCEDURE DtdElementFound (DtdElementRec : TDtdElementRec); VIRTUAL;
+ END;
+
+ TValueType = // --- Attribute Value Type
+ (vtNormal, // Normal specified Attribute
+ vtImplied, // #IMPLIED attribute value
+ vtFixed, // #FIXED attribute value
+ vtDefault); // Attribute value from default value in !ATTLIST declaration
+
+ TAttrDefault = // --- Attribute Default Type
+ (adDefault, // Normal default value
+ adRequired, // #REQUIRED attribute
+ adImplied, // #IMPLIED attribute
+ adFixed); // #FIXED attribute
+
+ TAttrType = // --- Type of attribute
+ (atUnknown, // Unknown type
+ atCData, // Character data only
+ atID, // ID
+ atIdRef, // ID Reference
+ atIdRefs, // Several ID References, separated by Whitespace
+ atEntity, // Name of an unparsed Entity
+ atEntities, // Several unparsed Entity names, separated by Whitespace
+ atNmToken, // Name Token
+ atNmTokens, // Several Name Tokens, separated by Whitespace
+ atNotation, // A selection of Notation names (Unparsed Entity)
+ atEnumeration); // Enumeration
+
+ TElemType = // --- Element content type
+ (etEmpty, // Element is always empty
+ etAny, // Element can have any mixture of PCDATA and any elements
+ etChildren, // Element must contain only elements
+ etMixed); // Mixed PCDATA and elements
+
+ (*$IFDEF HAS_CONTNRS_UNIT *)
+ TObjectList = Contnrs.TObjectList; // Re-Export this identifier
+ (*$ELSE *)
+ TObjectList = CLASS (TList)
+ DESTRUCTOR Destroy; OVERRIDE;
+ PROCEDURE Delete (Index : INTEGER);
+ PROCEDURE Clear; OVERRIDE;
+ END;
+ (*$ENDIF *)
+
+ TNvpNode = CLASS // Name-Value Pair Node
+ Name : STRING;
+ Value : STRING;
+ CONSTRUCTOR Create (TheName : STRING = ''; TheValue : STRING = '');
+ END;
+
+ TNvpList = CLASS (TObjectList) // Name-Value Pair List
+ PROCEDURE Add (Node : TNvpNode);
+ FUNCTION Node (Name : STRING) : TNvpNode; OVERLOAD;
+ FUNCTION Node (Index : INTEGER) : TNvpNode; OVERLOAD;
+ FUNCTION Value (Name : STRING) : STRING; OVERLOAD;
+ FUNCTION Value (Index : INTEGER) : STRING; OVERLOAD;
+ FUNCTION Name (Index : INTEGER) : STRING;
+ END;
+
+ TAttr = CLASS (TNvpNode) // Attribute of a Start-Tag or Empty-Element-Tag
+ ValueType : TValueType;
+ AttrType : TAttrType;
+ END;
+
+ TAttrList = CLASS (TNvpList) // List of Attributes
+ PROCEDURE Analyze (Start : PChar; VAR Final : PChar);
+ END;
+
+ TEntityStack = CLASS (TObjectList) // Stack where current position is stored before parsing entities
+ PROTECTED
+ Owner : TXmlParser;
+ PUBLIC
+ CONSTRUCTOR Create (TheOwner : TXmlParser);
+ PROCEDURE Push (LastPos : PChar); OVERLOAD;
+ PROCEDURE Push (Instance : TObject; LastPos : PChar); OVERLOAD;
+ FUNCTION Pop : PChar; // Returns next char or NIL if EOF is reached. Frees Instance.
+ END;
+
+ TAttrDef = CLASS (TNvpNode) // Represents a <!ATTLIST Definition. "Value" is the default value
+ TypeDef : STRING; // Type definition from the DTD
+ Notations : STRING; // Notation List, separated by pipe symbols '|'
+ AttrType : TAttrType; // Attribute Type
+ DefaultType : TAttrDefault; // Default Type
+ END;
+
+ TElemDef = CLASS (TNvpList) // Represents a <!ELEMENT Definition. Is a list of TAttrDef-Nodes
+ Name : STRING; // Element name
+ ElemType : TElemType; // Element type
+ Definition : STRING; // Element definition from DTD
+ END;
+
+ TElemList = CLASS (TObjectList) // List of TElemDef nodes
+ FUNCTION Node (Name : STRING) : TElemDef;
+ PROCEDURE Add (Node : TElemDef);
+ END;
+
+ TEntityDef = CLASS (TNvpNode) // Represents a <!ENTITY Definition.
+ SystemId : STRING;
+ PublicId : STRING;
+ NotationName : STRING;
+ END;
+
+ TNotationDef = CLASS (TNvpNode) // Represents a <!NOTATION Definition. Value is the System ID
+ PublicId : STRING;
+ END;
+
+ TCharset = SET OF CHAR;
+
+
+CONST
+ CWhitespace = [#32, #9, #13, #10]; // Whitespace characters (XmlSpec 2.3)
+ CLetter = [#$41..#$5A, #$61..#$7A, #$C0..#$D6, #$D8..#$F6, #$F8..#$FF];
+ CDigit = [#$30..#$39];
+ CNameChar = CLetter + CDigit + ['.', '-', '_', ':', #$B7];
+ CNameStart = CLetter + ['_', ':'];
+ CQuoteChar = ['"', ''''];
+ CPubidChar = [#32, ^M, ^J, #9, 'a'..'z', 'A'..'Z', '0'..'9',
+ '-', '''', '(', ')', '+', ',', '.', '/', ':',
+ '=', '?', ';', '!', '*', '#', '@', '$', '_', '%'];
+
+ CDStart = '<![CDATA[';
+ CDEnd = ']]>';
+
+ // --- Name Constants for the above enumeration types
+ CPartType_Name : ARRAY [TPartType] OF STRING =
+ ('', 'XML Prolog', 'Comment', 'PI',
+ 'DTD Declaration', 'Start Tag', 'Empty Tag', 'End Tag',
+ 'Text', 'CDATA');
+ CValueType_Name : ARRAY [TValueType] OF STRING = ('Normal', 'Implied', 'Fixed', 'Default');
+ CAttrDefault_Name : ARRAY [TAttrDefault] OF STRING = ('Default', 'Required', 'Implied', 'Fixed');
+ CElemType_Name : ARRAY [TElemType] OF STRING = ('Empty', 'Any', 'Childs only', 'Mixed');
+ CAttrType_Name : ARRAY [TAttrType] OF STRING = ('Unknown', 'CDATA',
+ 'ID', 'IDREF', 'IDREFS',
+ 'ENTITY', 'ENTITIES',
+ 'NMTOKEN', 'NMTOKENS',
+ 'Notation', 'Enumeration');
+
+FUNCTION ConvertWs (Source: STRING; PackWs: BOOLEAN) : STRING; // Convert WS to spaces #x20
+PROCEDURE SetStringSF (VAR S : STRING; BufferStart, BufferFinal : PChar); // SetString by Start/Final of buffer
+FUNCTION StrSFPas (Start, Finish : PChar) : STRING; // Convert buffer part to Pascal string
+FUNCTION TrimWs (Source : STRING) : STRING; // Trim Whitespace
+
+FUNCTION AnsiToUtf8 (Source : ANSISTRING) : STRING; // Convert Win-1252 to UTF-8
+FUNCTION Utf8ToAnsi (Source : STRING; UnknownChar : CHAR = '¿') : ANSISTRING; // Convert UTF-8 to Win-1252
+
+
+(*
+===============================================================================================
+TCustomXmlScanner event based component wrapper for TXmlParser
+===============================================================================================
+*)
+
+TYPE
+ TCustomXmlScanner = CLASS;
+ TXmlPrologEvent = PROCEDURE (Sender : TObject; XmlVersion, Encoding: STRING; Standalone : BOOLEAN) OF OBJECT;
+ TCommentEvent = PROCEDURE (Sender : TObject; Comment : STRING) OF OBJECT;
+ TPIEvent = PROCEDURE (Sender : TObject; Target, Content: STRING; Attributes : TAttrList) OF OBJECT;
+ TDtdEvent = PROCEDURE (Sender : TObject; RootElementName : STRING) OF OBJECT;
+ TStartTagEvent = PROCEDURE (Sender : TObject; TagName : STRING; Attributes : TAttrList) OF OBJECT;
+ TEndTagEvent = PROCEDURE (Sender : TObject; TagName : STRING) OF OBJECT;
+ TContentEvent = PROCEDURE (Sender : TObject; Content : STRING) OF OBJECT;
+ TElementEvent = PROCEDURE (Sender : TObject; ElemDef : TElemDef) OF OBJECT;
+ TEntityEvent = PROCEDURE (Sender : TObject; EntityDef : TEntityDef) OF OBJECT;
+ TNotationEvent = PROCEDURE (Sender : TObject; NotationDef : TNotationDef) OF OBJECT;
+ TErrorEvent = PROCEDURE (Sender : TObject; ErrorPos : PChar) OF OBJECT;
+ TExternalEvent = PROCEDURE (Sender : TObject; SystemId, PublicId, NotationId : STRING;
+ VAR Result : TXmlParser) OF OBJECT;
+ TEncodingEvent = FUNCTION (Sender : TObject; CurrentEncoding, Source : STRING) : STRING OF OBJECT;
+
+
+ TCustomXmlScanner = CLASS (TComponent)
+ PROTECTED
+ FXmlParser : TXmlParser;
+ FOnXmlProlog : TXmlPrologEvent;
+ FOnComment : TCommentEvent;
+ FOnPI : TPIEvent;
+ FOnDtdRead : TDtdEvent;
+ FOnStartTag : TStartTagEvent;
+ FOnEmptyTag : TStartTagEvent;
+ FOnEndTag : TEndTagEvent;
+ FOnContent : TContentEvent;
+ FOnCData : TContentEvent;
+ FOnElement : TElementEvent;
+ FOnAttList : TElementEvent;
+ FOnEntity : TEntityEvent;
+ FOnNotation : TNotationEvent;
+ FOnDtdError : TErrorEvent;
+ FOnLoadExternal : TExternalEvent;
+ FOnTranslateEncoding : TEncodingEvent;
+ FStopParser : BOOLEAN;
+ FUNCTION GetNormalize : BOOLEAN;
+ PROCEDURE SetNormalize (Value : BOOLEAN);
+
+ PROCEDURE WhenXmlProlog(XmlVersion, Encoding: STRING; Standalone : BOOLEAN); VIRTUAL;
+ PROCEDURE WhenComment (Comment : STRING); VIRTUAL;
+ PROCEDURE WhenPI (Target, Content: STRING; Attributes : TAttrList); VIRTUAL;
+ PROCEDURE WhenDtdRead (RootElementName : STRING); VIRTUAL;
+ PROCEDURE WhenStartTag (TagName : STRING; Attributes : TAttrList); VIRTUAL;
+ PROCEDURE WhenEmptyTag (TagName : STRING; Attributes : TAttrList); VIRTUAL;
+ PROCEDURE WhenEndTag (TagName : STRING); VIRTUAL;
+ PROCEDURE WhenContent (Content : STRING); VIRTUAL;
+ PROCEDURE WhenCData (Content : STRING); VIRTUAL;
+ PROCEDURE WhenElement (ElemDef : TElemDef); VIRTUAL;
+ PROCEDURE WhenAttList (ElemDef : TElemDef); VIRTUAL;
+ PROCEDURE WhenEntity (EntityDef : TEntityDef); VIRTUAL;
+ PROCEDURE WhenNotation (NotationDef : TNotationDef); VIRTUAL;
+ PROCEDURE WhenDtdError (ErrorPos : PChar); VIRTUAL;
+
+ PUBLIC
+ CONSTRUCTOR Create (AOwner: TComponent); OVERRIDE;
+ DESTRUCTOR Destroy; OVERRIDE;
+
+ PROCEDURE LoadFromFile (Filename : TFilename); // Load XML Document from file
+ PROCEDURE LoadFromBuffer (Buffer : PChar); // Load XML Document from buffer
+ PROCEDURE SetBuffer (Buffer : PChar); // Refer to Buffer
+ FUNCTION GetFilename : TFilename;
+
+ PROCEDURE Execute; // Perform scanning
+
+ PROTECTED
+ PROPERTY XmlParser : TXmlParser READ FXmlParser;
+ PROPERTY StopParser : BOOLEAN READ FStopParser WRITE FStopParser;
+ PROPERTY Filename : TFilename READ GetFilename WRITE LoadFromFile;
+ PROPERTY Normalize : BOOLEAN READ GetNormalize WRITE SetNormalize;
+ PROPERTY OnXmlProlog : TXmlPrologEvent READ FOnXmlProlog WRITE FOnXmlProlog;
+ PROPERTY OnComment : TCommentEvent READ FOnComment WRITE FOnComment;
+ PROPERTY OnPI : TPIEvent READ FOnPI WRITE FOnPI;
+ PROPERTY OnDtdRead : TDtdEvent READ FOnDtdRead WRITE FOnDtdRead;
+ PROPERTY OnStartTag : TStartTagEvent READ FOnStartTag WRITE FOnStartTag;
+ PROPERTY OnEmptyTag : TStartTagEvent READ FOnEmptyTag WRITE FOnEmptyTag;
+ PROPERTY OnEndTag : TEndTagEvent READ FOnEndTag WRITE FOnEndTag;
+ PROPERTY OnContent : TContentEvent READ FOnContent WRITE FOnContent;
+ PROPERTY OnCData : TContentEvent READ FOnCData WRITE FOnCData;
+ PROPERTY OnElement : TElementEvent READ FOnElement WRITE FOnElement;
+ PROPERTY OnAttList : TElementEvent READ FOnAttList WRITE FOnAttList;
+ PROPERTY OnEntity : TEntityEvent READ FOnEntity WRITE FOnEntity;
+ PROPERTY OnNotation : TNotationEvent READ FOnNotation WRITE FOnNotation;
+ PROPERTY OnDtdError : TErrorEvent READ FOnDtdError WRITE FOnDtdError;
+ PROPERTY OnLoadExternal : TExternalEvent READ FOnLoadExternal WRITE FOnLoadExternal;
+ PROPERTY OnTranslateEncoding : TEncodingEvent READ FOnTranslateEncoding WRITE FOnTranslateEncoding;
+ END;
+
+(*
+===============================================================================================
+IMPLEMENTATION
+===============================================================================================
+*)
+
+IMPLEMENTATION
+
+
+(*
+===============================================================================================
+Unicode and UTF-8 stuff
+===============================================================================================
+*)
+
+CONST
+ // --- Character Translation Table for Unicode <-> Win-1252
+ WIN1252_UNICODE : ARRAY [$00..$FF] OF WORD = (
+ $0000, $0001, $0002, $0003, $0004, $0005, $0006, $0007, $0008, $0009,
+ $000A, $000B, $000C, $000D, $000E, $000F, $0010, $0011, $0012, $0013,
+ $0014, $0015, $0016, $0017, $0018, $0019, $001A, $001B, $001C, $001D,
+ $001E, $001F, $0020, $0021, $0022, $0023, $0024, $0025, $0026, $0027,
+ $0028, $0029, $002A, $002B, $002C, $002D, $002E, $002F, $0030, $0031,
+ $0032, $0033, $0034, $0035, $0036, $0037, $0038, $0039, $003A, $003B,
+ $003C, $003D, $003E, $003F, $0040, $0041, $0042, $0043, $0044, $0045,
+ $0046, $0047, $0048, $0049, $004A, $004B, $004C, $004D, $004E, $004F,
+ $0050, $0051, $0052, $0053, $0054, $0055, $0056, $0057, $0058, $0059,
+ $005A, $005B, $005C, $005D, $005E, $005F, $0060, $0061, $0062, $0063,
+ $0064, $0065, $0066, $0067, $0068, $0069, $006A, $006B, $006C, $006D,
+ $006E, $006F, $0070, $0071, $0072, $0073, $0074, $0075, $0076, $0077,
+ $0078, $0079, $007A, $007B, $007C, $007D, $007E, $007F,
+
+ $20AC, $0081, $201A, $0192, $201E, $2026, $2020, $2021, $02C6, $2030,
+ $0160, $2039, $0152, $008D, $017D, $008F, $0090, $2018, $2019, $201C,
+ $201D, $2022, $2013, $2014, $02DC, $2122, $0161, $203A, $0153, $009D,
+ $017E, $0178, $00A0, $00A1, $00A2, $00A3, $00A4, $00A5, $00A6, $00A7,
+ $00A8, $00A9, $00AA, $00AB, $00AC, $00AD, $00AE, $00AF, $00B0, $00B1,
+ $00B2, $00B3, $00B4, $00B5, $00B6, $00B7, $00B8, $00B9, $00BA, $00BB,
+ $00BC, $00BD, $00BE, $00BF, $00C0, $00C1, $00C2, $00C3, $00C4, $00C5,
+ $00C6, $00C7, $00C8, $00C9, $00CA, $00CB, $00CC, $00CD, $00CE, $00CF,
+ $00D0, $00D1, $00D2, $00D3, $00D4, $00D5, $00D6, $00D7, $00D8, $00D9,
+ $00DA, $00DB, $00DC, $00DD, $00DE, $00DF, $00E0, $00E1, $00E2, $00E3,
+ $00E4, $00E5, $00E6, $00E7, $00E8, $00E9, $00EA, $00EB, $00EC, $00ED,
+ $00EE, $00EF, $00F0, $00F1, $00F2, $00F3, $00F4, $00F5, $00F6, $00F7,
+ $00F8, $00F9, $00FA, $00FB, $00FC, $00FD, $00FE, $00FF);
+
+(* UTF-8 (somewhat simplified)
+ -----
+ Character Range Byte sequence
+ --------------- -------------------------- (x=Bits from original character)
+ $0000..$007F 0xxxxxxx
+ $0080..$07FF 110xxxxx 10xxxxxx
+ $8000..$FFFF 1110xxxx 10xxxxxx 10xxxxxx
+
+ Example
+ --------
+ Transforming the Unicode character U+00E4 LATIN SMALL LETTER A WITH DIAERESIS ("ä"):
+
+ ISO-8859-1, Decimal 228
+ Win1252, Hex $E4
+ ANSI Bin 1110 0100
+ abcd efgh
+
+ UTF-8 Binary 1100xxab 10cdefgh
+ Binary 11000011 10100100
+ Hex $C3 $A4
+ Decimal 195 164
+ ANSI Ã ¤ *)
+
+
+FUNCTION AnsiToUtf8 (Source : ANSISTRING) : STRING;
+ (* Converts the given Windows ANSI (Win1252) String to UTF-8. *)
+VAR
+ I : INTEGER; // Loop counter
+ U : WORD; // Current Unicode value
+ Len : INTEGER; // Current real length of "Result" string
+BEGIN
+ SetLength (Result, Length (Source) * 3); // Worst case
+ Len := 0;
+ FOR I := 1 TO Length (Source) DO BEGIN
+ U := WIN1252_UNICODE [ORD (Source [I])];
+ CASE U OF
+ $0000..$007F : BEGIN
+ INC (Len);
+ Result [Len] := CHR (U);
+ END;
+ $0080..$07FF : BEGIN
+ INC (Len);
+ Result [Len] := CHR ($C0 OR (U SHR 6));
+ INC (Len);
+ Result [Len] := CHR ($80 OR (U AND $3F));
+ END;
+ $0800..$FFFF : BEGIN
+ INC (Len);
+ Result [Len] := CHR ($E0 OR (U SHR 12));
+ INC (Len);
+ Result [Len] := CHR ($80 OR ((U SHR 6) AND $3F));
+ INC (Len);
+ Result [Len] := CHR ($80 OR (U AND $3F));
+ END;
+ END;
+ END;
+ SetLength (Result, Len);
+END;
+
+
+FUNCTION Utf8ToAnsi (Source : STRING; UnknownChar : CHAR = '¿') : ANSISTRING;
+ (* Converts the given UTF-8 String to Windows ANSI (Win-1252).
+ If a character can not be converted, the "UnknownChar" is inserted. *)
+VAR
+ SourceLen : INTEGER; // Length of Source string
+ I, K : INTEGER;
+ A : BYTE; // Current ANSI character value
+ U : WORD;
+ Ch : CHAR; // Dest char
+ Len : INTEGER; // Current real length of "Result" string
+BEGIN
+ SourceLen := Length (Source);
+ SetLength (Result, SourceLen); // Enough room to live
+ Len := 0;
+ I := 1;
+ WHILE I <= SourceLen DO BEGIN
+ A := ORD (Source [I]);
+ IF A < $80 THEN BEGIN // Range $0000..$007F
+ INC (Len);
+ Result [Len] := Source [I];
+ INC (I);
+ END
+ ELSE BEGIN // Determine U, Inc I
+ IF (A AND $E0 = $C0) AND (I < SourceLen) THEN BEGIN // Range $0080..$07FF
+ U := (WORD (A AND $1F) SHL 6) OR (ORD (Source [I+1]) AND $3F);
+ INC (I, 2);
+ END
+ ELSE IF (A AND $F0 = $E0) AND (I < SourceLen-1) THEN BEGIN // Range $0800..$FFFF
+ U := (WORD (A AND $0F) SHL 12) OR
+ (WORD (ORD (Source [I+1]) AND $3F) SHL 6) OR
+ ( ORD (Source [I+2]) AND $3F);
+ INC (I, 3);
+ END
+ ELSE BEGIN // Unknown/unsupported
+ INC (I);
+ FOR K := 7 DOWNTO 0 DO
+ IF A AND (1 SHL K) = 0 THEN BEGIN
+ INC (I, (A SHR (K+1))-1);
+ BREAK;
+ END;
+ U := WIN1252_UNICODE [ORD (UnknownChar)];
+ END;
+ Ch := UnknownChar; // Retrieve ANSI char
+ FOR A := $00 TO $FF DO
+ IF WIN1252_UNICODE [A] = U THEN BEGIN
+ Ch := CHR (A);
+ BREAK;
+ END;
+ INC (Len);
+ Result [Len] := Ch;
+ END;
+ END;
+ SetLength (Result, Len);
+END;
+
+
+(*
+===============================================================================================
+"Special" Helper Functions
+
+Don't ask me why. But including these functions makes the parser *DRAMATICALLY* faster
+on my K6-233 machine. You can test it yourself just by commenting them out.
+They do exactly the same as the Assembler routines defined in SysUtils.
+(This is where you can see how great the Delphi compiler really is. The compiled code is
+faster than hand-coded assembler!)
+===============================================================================================
+--> Just move this line below the StrScan function --> *)
+
+
+FUNCTION StrPos (CONST Str, SearchStr : PChar) : PChar;
+ // Same functionality as SysUtils.StrPos
+VAR
+ First : CHAR;
+ Len : INTEGER;
+BEGIN
+ First := SearchStr^;
+ Len := StrLen (SearchStr);
+ Result := Str;
+ REPEAT
+ IF Result^ = First THEN
+ IF StrLComp (Result, SearchStr, Len) = 0 THEN BREAK;
+ IF Result^ = #0 THEN BEGIN
+ Result := NIL;
+ BREAK;
+ END;
+ INC (Result);
+ UNTIL FALSE;
+END;
+
+
+FUNCTION StrScan (CONST Start : PChar; CONST Ch : CHAR) : PChar;
+ // Same functionality as SysUtils.StrScan
+BEGIN
+ Result := Start;
+ WHILE Result^ <> Ch DO BEGIN
+ IF Result^ = #0 THEN BEGIN
+ Result := NIL;
+ EXIT;
+ END;
+ INC (Result);
+ END;
+END;
+
+
+(*
+===============================================================================================
+Helper Functions
+===============================================================================================
+*)
+
+FUNCTION DelChars (Source : STRING; CharsToDelete : TCharset) : STRING;
+ // Delete all "CharsToDelete" from the string
+VAR
+ I : INTEGER;
+BEGIN
+ Result := Source;
+ FOR I := Length (Result) DOWNTO 1 DO
+ IF Result [I] IN CharsToDelete THEN
+ Delete (Result, I, 1);
+END;
+
+
+FUNCTION TrimWs (Source : STRING) : STRING;
+ // Trimms off Whitespace characters from both ends of the string
+VAR
+ I : INTEGER;
+BEGIN
+ // --- Trim Left
+ I := 1;
+ WHILE (I <= Length (Source)) AND (Source [I] IN CWhitespace) DO
+ INC (I);
+ Result := Copy (Source, I, MaxInt);
+
+ // --- Trim Right
+ I := Length (Result);
+ WHILE (I > 1) AND (Result [I] IN CWhitespace) DO
+ DEC (I);
+ Delete (Result, I+1, Length (Result)-I);
+END;
+
+
+FUNCTION ConvertWs (Source: STRING; PackWs: BOOLEAN) : STRING;
+ // Converts all Whitespace characters to the Space #x20 character
+ // If "PackWs" is true, contiguous Whitespace characters are packed to one
+VAR
+ I : INTEGER;
+BEGIN
+ Result := Source;
+ FOR I := Length (Result) DOWNTO 1 DO
+ IF (Result [I] IN CWhitespace) THEN
+ IF PackWs AND (I > 1) AND (Result [I-1] IN CWhitespace)
+ THEN Delete (Result, I, 1)
+ ELSE Result [I] := #32;
+END;
+
+
+PROCEDURE SetStringSF (VAR S : STRING; BufferStart, BufferFinal : PChar);
+BEGIN
+ SetString (S, BufferStart, BufferFinal-BufferStart+1);
+END;
+
+
+FUNCTION StrLPas (Start : PChar; Len : INTEGER) : STRING;
+BEGIN
+ SetString (Result, Start, Len);
+END;
+
+
+FUNCTION StrSFPas (Start, Finish : PChar) : STRING;
+BEGIN
+ SetString (Result, Start, Finish-Start+1);
+END;
+
+
+FUNCTION StrScanE (CONST Source : PChar; CONST CharToScanFor : CHAR) : PChar;
+ // If "CharToScanFor" is not found, StrScanE returns the last char of the
+ // buffer instead of NIL
+BEGIN
+ Result := StrScan (Source, CharToScanFor);
+ IF Result = NIL THEN
+ Result := StrEnd (Source)-1;
+END;
+
+
+PROCEDURE ExtractName (Start : PChar; Terminators : TCharset; VAR Final : PChar);
+ (* Extracts the complete Name beginning at "Start".
+ It is assumed that the name is contained in Markup, so the '>' character is
+ always a Termination.
+ Start: IN Pointer to first char of name. Is always considered to be valid
+ Terminators: IN Characters which terminate the name
+ Final: OUT Pointer to last char of name *)
+BEGIN
+ Final := Start+1;
+ Include (Terminators, #0);
+ Include (Terminators, '>');
+ WHILE NOT (Final^ IN Terminators) DO
+ INC (Final);
+ DEC (Final);
+END;
+
+
+PROCEDURE ExtractQuote (Start : PChar; VAR Content : STRING; VAR Final : PChar);
+ (* Extract a string which is contained in single or double Quotes.
+ Start: IN Pointer to opening quote
+ Content: OUT The quoted string
+ Final: OUT Pointer to closing quote *)
+BEGIN
+ Final := StrScan (Start+1, Start^);
+ IF Final = NIL THEN BEGIN
+ Final := StrEnd (Start+1)-1;
+ SetString (Content, Start+1, Final-Start);
+ END
+ ELSE
+ SetString (Content, Start+1, Final-1-Start);
+END;
+
+
+(*
+===============================================================================================
+TEntityStackNode
+This Node is pushed to the "Entity Stack" whenever the parser parses entity replacement text.
+The "Instance" field holds the Instance pointer of an External Entity buffer. When it is
+popped, the Instance is freed.
+The "Encoding" field holds the name of the Encoding. External Parsed Entities may have
+another encoding as the document entity (XmlSpec 4.3.3). So when there is an "<?xml" PI
+found in the stream (= Text Declaration at the beginning of external parsed entities), the
+Encoding found there is used for the External Entity (is assigned to TXmlParser.CurEncoding)
+Default Encoding is for the Document Entity is UTF-8. It is assumed that External Entities
+have the same Encoding as the Document Entity, unless they carry a Text Declaration.
+===============================================================================================
+*)
+
+TYPE
+ TEntityStackNode = CLASS
+ Instance : TObject;
+ Encoding : STRING;
+ LastPos : PChar;
+ END;
+
+(*
+===============================================================================================
+TEntityStack
+For nesting of Entities.
+When there is an entity reference found in the data stream, the corresponding entity
+definition is searched and the current position is pushed to this stack.
+From then on, the program scans the entitiy replacement text as if it were normal content.
+When the parser reaches the end of an entity, the current position is popped off the
+stack again.
+===============================================================================================
+*)
+
+CONSTRUCTOR TEntityStack.Create (TheOwner : TXmlParser);
+BEGIN
+ INHERITED Create;
+ Owner := TheOwner;
+END;
+
+
+PROCEDURE TEntityStack.Push (LastPos : PChar);
+BEGIN
+ Push (NIL, LastPos);
+END;
+
+
+PROCEDURE TEntityStack.Push (Instance : TObject; LastPos : PChar);
+VAR
+ ESN : TEntityStackNode;
+BEGIN
+ ESN := TEntityStackNode.Create;
+ ESN.Instance := Instance;
+ ESN.Encoding := Owner.FCurEncoding; // Save current Encoding
+ ESN.LastPos := LastPos;
+ Add (ESN);
+END;
+
+
+FUNCTION TEntityStack.Pop : PChar;
+VAR
+ ESN : TEntityStackNode;
+BEGIN
+ IF Count > 0 THEN BEGIN
+ ESN := TEntityStackNode (Items [Count-1]);
+ Result := ESN.LastPos;
+ IF ESN.Instance <> NIL THEN
+ ESN.Instance.Free;
+ IF ESN.Encoding <> '' THEN
+ Owner.FCurEncoding := ESN.Encoding; // Restore current Encoding
+ Delete (Count-1);
+ END
+ ELSE
+ Result := NIL;
+END;
+
+
+(*
+===============================================================================================
+TExternalID
+-----------
+XmlSpec 4.2.2: ExternalID ::= 'SYSTEM' S SystemLiteral |
+ 'PUBLIC' S PubidLiteral S SystemLiteral
+XmlSpec 4.7: PublicID ::= 'PUBLIC' S PubidLiteral
+SystemLiteral and PubidLiteral are quoted
+===============================================================================================
+*)
+
+TYPE
+ TExternalID = CLASS
+ PublicId : STRING;
+ SystemId : STRING;
+ Final : PChar;
+ CONSTRUCTOR Create (Start : PChar);
+ END;
+
+CONSTRUCTOR TExternalID.Create (Start : PChar);
+BEGIN
+ INHERITED Create;
+ Final := Start;
+ IF StrLComp (Start, 'SYSTEM', 6) = 0 THEN BEGIN
+ WHILE NOT (Final^ IN (CQuoteChar + [#0, '>', '['])) DO INC (Final);
+ IF NOT (Final^ IN CQuoteChar) THEN EXIT;
+ ExtractQuote (Final, SystemID, Final);
+ END
+ ELSE IF StrLComp (Start, 'PUBLIC', 6) = 0 THEN BEGIN
+ WHILE NOT (Final^ IN (CQuoteChar + [#0, '>', '['])) DO INC (Final);
+ IF NOT (Final^ IN CQuoteChar) THEN EXIT;
+ ExtractQuote (Final, PublicID, Final);
+ INC (Final);
+ WHILE NOT (Final^ IN (CQuoteChar + [#0, '>', '['])) DO INC (Final);
+ IF NOT (Final^ IN CQuoteChar) THEN EXIT;
+ ExtractQuote (Final, SystemID, Final);
+ END;
+END;
+
+
+(*
+===============================================================================================
+TXmlParser
+===============================================================================================
+*)
+
+CONSTRUCTOR TXmlParser.Create;
+BEGIN
+ INHERITED Create;
+ FBuffer := NIL;
+ FBufferSize := 0;
+ Elements := TElemList.Create;
+ Entities := TNvpList.Create;
+ ParEntities := TNvpList.Create;
+ Notations := TNvpList.Create;
+ CurAttr := TAttrList.Create;
+ EntityStack := TEntityStack.Create (Self);
+ Clear;
+END;
+
+
+DESTRUCTOR TXmlParser.Destroy;
+BEGIN
+ Clear;
+ Elements.Free;
+ Entities.Free;
+ ParEntities.Free;
+ Notations.Free;
+ CurAttr.Free;
+ EntityStack.Free;
+ INHERITED Destroy;
+END;
+
+
+PROCEDURE TXmlParser.Clear;
+ // Free Buffer and clear all object attributes
+BEGIN
+ IF (FBufferSize > 0) AND (FBuffer <> NIL) THEN
+ FreeMem (FBuffer);
+ FBuffer := NIL;
+ FBufferSize := 0;
+ FSource := '';
+ FXmlVersion := '';
+ FEncoding := '';
+ FStandalone := FALSE;
+ FRootName := '';
+ FDtdcFinal := NIL;
+ FNormalize := TRUE;
+ Elements.Clear;
+ Entities.Clear;
+ ParEntities.Clear;
+ Notations.Clear;
+ CurAttr.Clear;
+ EntityStack.Clear;
+END;
+
+
+FUNCTION TXmlParser.LoadFromFile (Filename : STRING; FileMode : INTEGER = fmOpenRead OR fmShareDenyNone) : BOOLEAN;
+ // Loads Document from given file
+ // Returns TRUE if successful
+VAR
+ f : FILE;
+ ReadIn : INTEGER;
+ OldFileMode : INTEGER;
+BEGIN
+ Result := FALSE;
+ Clear;
+
+ // --- Open File
+ OldFileMode := SYSTEM.FileMode;
+ TRY
+ SYSTEM.FileMode := FileMode;
+ TRY
+ AssignFile (f, Filename);
+ Reset (f, 1);
+ EXCEPT
+ EXIT;
+ END;
+
+ TRY
+ // --- Allocate Memory
+ TRY
+ FBufferSize := Filesize (f) + 1;
+ GetMem (FBuffer, FBufferSize);
+ EXCEPT
+ Clear;
+ EXIT;
+ END;
+
+ // --- Read File
+ TRY
+ BlockRead (f, FBuffer^, FBufferSize, ReadIn);
+ (FBuffer+ReadIn)^ := #0; // NULL termination
+ EXCEPT
+ Clear;
+ EXIT;
+ END;
+ FINALLY
+ CloseFile (f);
+ END;
+
+ FSource := Filename;
+ Result := TRUE;
+
+ FINALLY
+ SYSTEM.FileMode := OldFileMode;
+ END;
+END;
+
+
+FUNCTION TXmlParser.LoadFromBuffer (Buffer : PChar) : BOOLEAN;
+ // Loads Document from another buffer
+ // Returns TRUE if successful
+ // The "Source" property becomes '<MEM>' if successful
+BEGIN
+ Result := FALSE;
+ Clear;
+ FBufferSize := StrLen (Buffer) + 1;
+ TRY
+ GetMem (FBuffer, FBufferSize);
+ EXCEPT
+ Clear;
+ EXIT;
+ END;
+ StrCopy (FBuffer, Buffer);
+ FSource := '<MEM>';
+ Result := TRUE;
+END;
+
+
+PROCEDURE TXmlParser.SetBuffer (Buffer : PChar); // References another buffer
+BEGIN
+ Clear;
+ FBuffer := Buffer;
+ FBufferSize := 0;
+ FSource := '<REFERENCE>';
+END;
+
+
+//-----------------------------------------------------------------------------------------------
+// Scanning through the document
+//-----------------------------------------------------------------------------------------------
+
+PROCEDURE TXmlParser.StartScan;
+BEGIN
+ CurPartType := ptNone;
+ CurName := '';
+ CurContent := '';
+ CurStart := NIL;
+ CurFinal := NIL;
+ CurAttr.Clear;
+ EntityStack.Clear;
+END;
+
+
+FUNCTION TXmlParser.Scan : BOOLEAN;
+ // Scans the next Part
+ // Returns TRUE if a part could be found, FALSE if there is no part any more
+ //
+ // "IsDone" can be set to FALSE by AnalyzeText in order to go to the next part
+ // if there is no Content due to normalization
+VAR
+ IsDone : BOOLEAN;
+BEGIN
+ REPEAT
+ IsDone := TRUE;
+
+ // --- Start of next Part
+ IF CurStart = NIL
+ THEN CurStart := DocBuffer
+ ELSE CurStart := CurFinal+1;
+ CurFinal := CurStart;
+
+ // --- End of Document of Pop off a new part from the Entity stack?
+ IF CurStart^ = #0 THEN
+ CurStart := EntityStack.Pop;
+
+ // --- No Document or End Of Document: Terminate Scan
+ IF (CurStart = NIL) OR (CurStart^ = #0) THEN BEGIN
+ CurStart := StrEnd (DocBuffer);
+ CurFinal := CurStart-1;
+ EntityStack.Clear;
+ Result := FALSE;
+ EXIT;
+ END;
+
+ IF (StrLComp (CurStart, '<?xml', 5) = 0) AND
+ ((CurStart+5)^ IN CWhitespace) THEN AnalyzeProlog // XML Declaration, Text Declaration
+ ELSE IF StrLComp (CurStart, '<?', 2) = 0 THEN AnalyzePI (CurStart, CurFinal) // PI
+ ELSE IF StrLComp (CurStart, '<!--', 4) = 0 THEN AnalyzeComment (CurStart, CurFinal) // Comment
+ ELSE IF StrLComp (CurStart, '<!DOCTYPE', 9) = 0 THEN AnalyzeDtdc // DTDc
+ ELSE IF StrLComp (CurStart, CDStart, Length (CDStart)) = 0 THEN AnalyzeCdata // CDATA Section
+ ELSE IF StrLComp (CurStart, '<', 1) = 0 THEN AnalyzeTag // Start-Tag, End-Tag, Empty-Element-Tag
+ ELSE AnalyzeText (IsDone); // Text Content
+ UNTIL IsDone;
+ Result := TRUE;
+END;
+
+
+PROCEDURE TXmlParser.AnalyzeProlog;
+ // Analyze XML Prolog or Text Declaration
+VAR
+ F : PChar;
+BEGIN
+ CurAttr.Analyze (CurStart+5, F);
+ IF EntityStack.Count = 0 THEN BEGIN
+ FXmlVersion := CurAttr.Value ('version');
+ FEncoding := CurAttr.Value ('encoding');
+ FStandalone := CurAttr.Value ('standalone') = 'yes';
+ END;
+ CurFinal := StrPos (F, '?>');
+ IF CurFinal <> NIL
+ THEN INC (CurFinal)
+ ELSE CurFinal := StrEnd (CurStart)-1;
+ FCurEncoding := AnsiUpperCase (CurAttr.Value ('encoding'));
+ IF FCurEncoding = '' THEN
+ FCurEncoding := 'UTF-8'; // Default XML Encoding is UTF-8
+ CurPartType := ptXmlProlog;
+ CurName := '';
+ CurContent := '';
+END;
+
+
+PROCEDURE TXmlParser.AnalyzeComment (Start : PChar; VAR Final : PChar);
+ // Analyze Comments
+BEGIN
+ Final := StrPos (Start+4, '-->');
+ IF Final = NIL
+ THEN Final := StrEnd (Start)-1
+ ELSE INC (Final, 2);
+ CurPartType := ptComment;
+END;
+
+
+PROCEDURE TXmlParser.AnalyzePI (Start : PChar; VAR Final : PChar);
+ // Analyze Processing Instructions (PI)
+ // This is also called for Character
+VAR
+ F : PChar;
+BEGIN
+ CurPartType := ptPI;
+ Final := StrPos (Start+2, '?>');
+ IF Final = NIL
+ THEN Final := StrEnd (Start)-1
+ ELSE INC (Final);
+ ExtractName (Start+2, CWhitespace + ['?', '>'], F);
+ SetStringSF (CurName, Start+2, F);
+ SetStringSF (CurContent, F+1, Final-2);
+ CurAttr.Analyze (F+1, F);
+END;
+
+
+PROCEDURE TXmlParser.AnalyzeDtdc;
+ (* Analyze Document Type Declaration
+ doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S? ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
+ markupdecl ::= elementdecl | AttlistDecl | EntityDecl | NotationDecl | PI | Comment
+ PEReference ::= '%' Name ';'
+
+ elementdecl ::= '<!ELEMENT' S Name S contentspec S? '>'
+ AttlistDecl ::= '<!ATTLIST' S Name AttDef* S? '>'
+ EntityDecl ::= '<!ENTITY' S Name S EntityDef S? '>' |
+ '<!ENTITY' S '%' S Name S PEDef S? '>'
+ NotationDecl ::= '<!NOTATION' S Name S (ExternalID | PublicID) S? '>'
+ PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char* )))? '?>'
+ Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->' *)
+TYPE
+ TPhase = (phName, phDtd, phInternal, phFinishing);
+VAR
+ Phase : TPhase;
+ F : PChar;
+ ExternalID : TExternalID;
+ ExternalDTD : TXmlParser;
+ DER : TDtdElementRec;
+BEGIN
+ DER.Start := CurStart;
+ EntityStack.Clear; // Clear stack for Parameter Entities
+ CurPartType := ptDtdc;
+
+ // --- Don't read DTDc twice
+ IF FDtdcFinal <> NIL THEN BEGIN
+ CurFinal := FDtdcFinal;
+ EXIT;
+ END;
+
+ // --- Scan DTDc
+ CurFinal := CurStart + 9; // First char after '<!DOCTYPE'
+ Phase := phName;
+ REPEAT
+ CASE CurFinal^ OF
+ '%' : BEGIN
+ PushPE (CurFinal);
+ CONTINUE;
+ END;
+ #0 : IF EntityStack.Count = 0 THEN
+ BREAK
+ ELSE BEGIN
+ CurFinal := EntityStack.Pop;
+ CONTINUE;
+ END;
+ '[' : BEGIN
+ Phase := phInternal;
+ AnalyzeDtdElements (CurFinal+1, CurFinal);
+ CONTINUE;
+ END;
+ ']' : Phase := phFinishing;
+ '>' : BREAK;
+ ELSE IF NOT (CurFinal^ IN CWhitespace) THEN BEGIN
+ CASE Phase OF
+ phName : IF (CurFinal^ IN CNameStart) THEN BEGIN
+ ExtractName (CurFinal, CWhitespace + ['[', '>'], F);
+ SetStringSF (FRootName, CurFinal, F);
+ CurFinal := F;
+ Phase := phDtd;
+ END;
+ phDtd : IF (StrLComp (CurFinal, 'SYSTEM', 6) = 0) OR
+ (StrLComp (CurFinal, 'PUBLIC', 6) = 0) THEN BEGIN
+ ExternalID := TExternalID.Create (CurFinal);
+ ExternalDTD := LoadExternalEntity (ExternalId.SystemId, ExternalID.PublicId, '');
+ F := StrPos (ExternalDtd.DocBuffer, '<!');
+ IF F <> NIL THEN
+ AnalyzeDtdElements (F, F);
+ ExternalDTD.Free;
+ CurFinal := ExternalID.Final;
+ ExternalID.Free;
+ END;
+ ELSE BEGIN
+ DER.ElementType := deError;
+ DER.Pos := CurFinal;
+ DER.Final := CurFinal;
+ DtdElementFound (DER);
+ END;
+ END;
+
+ END;
+ END;
+ INC (CurFinal);
+ UNTIL FALSE;
+
+ CurPartType := ptDtdc;
+ CurName := '';
+ CurContent := '';
+
+ // It is an error in the document if "EntityStack" is not empty now
+ IF EntityStack.Count > 0 THEN BEGIN
+ DER.ElementType := deError;
+ DER.Final := CurFinal;
+ DER.Pos := CurFinal;
+ DtdElementFound (DER);
+ END;
+
+ EntityStack.Clear; // Clear stack for General Entities
+ FDtdcFinal := CurFinal;
+END;
+
+
+PROCEDURE TXmlParser.AnalyzeDtdElements (Start : PChar; VAR Final : PChar);
+ // Analyze the "Elements" of a DTD contained in the external or
+ // internal DTD subset.
+VAR
+ DER : TDtdElementRec;
+BEGIN
+ Final := Start;
+ REPEAT
+ CASE Final^ OF
+ '%' : BEGIN
+ PushPE (Final);
+ CONTINUE;
+ END;
+ #0 : IF EntityStack.Count = 0 THEN
+ BREAK
+ ELSE BEGIN
+ CurFinal := EntityStack.Pop;
+ CONTINUE;
+ END;
+ ']',
+ '>' : BREAK;
+ '<' : IF StrLComp (Final, '<!ELEMENT', 9) = 0 THEN AnalyzeElementDecl (Final, Final)
+ ELSE IF StrLComp (Final, '<!ATTLIST', 9) = 0 THEN AnalyzeAttListDecl (Final, Final)
+ ELSE IF StrLComp (Final, '<!ENTITY', 8) = 0 THEN AnalyzeEntityDecl (Final, Final)
+ ELSE IF StrLComp (Final, '<!NOTATION', 10) = 0 THEN AnalyzeNotationDecl (Final, Final)
+ ELSE IF StrLComp (Final, '<?', 2) = 0 THEN BEGIN // PI in DTD
+ DER.ElementType := dePI;
+ DER.Start := Final;
+ AnalyzePI (Final, Final);
+ DER.Target := PChar (CurName);
+ DER.Content := PChar (CurContent);
+ DER.AttrList := CurAttr;
+ DER.Final := Final;
+ DtdElementFound (DER);
+ END
+ ELSE IF StrLComp (Final, '<!--', 4) = 0 THEN BEGIN // Comment in DTD
+ DER.ElementType := deComment;
+ DER.Start := Final;
+ AnalyzeComment (Final, Final);
+ DER.Final := Final;
+ DtdElementFound (DER);
+ END
+ ELSE BEGIN
+ DER.ElementType := deError;
+ DER.Start := Final;
+ DER.Pos := Final;
+ DER.Final := Final;
+ DtdElementFound (DER);
+ END;
+
+ END;
+ INC (Final);
+ UNTIL FALSE;
+END;
+
+
+PROCEDURE TXmlParser.AnalyzeTag;
+ // Analyze Tags
+VAR
+ S, F : PChar;
+ Attr : TAttr;
+ ElemDef : TElemDef;
+ AttrDef : TAttrDef;
+ I : INTEGER;
+BEGIN
+ CurPartType := ptStartTag;
+ S := CurStart+1;
+ IF S^ = '/' THEN BEGIN
+ CurPartType := ptEndTag;
+ INC (S);
+ END;
+ ExtractName (S, CWhitespace + ['/'], F);
+ SetStringSF (CurName, S, F);
+ CurAttr.Analyze (F+1, CurFinal);
+ IF CurFinal^ = '/' THEN BEGIN
+ CurPartType := ptEmptyTag;
+ END;
+ CurFinal := StrScanE (CurFinal, '>');
+
+ // --- Set Default Attribute values for nonexistent attributes
+ IF (CurPartType = ptStartTag) OR (CurPartType = ptEmptyTag) THEN BEGIN
+ ElemDef := Elements.Node (CurName);
+ IF ElemDef <> NIL THEN BEGIN
+ FOR I := 0 TO ElemDef.Count-1 DO BEGIN
+ AttrDef := TAttrDef (ElemDef [I]);
+ Attr := TAttr (CurAttr.Node (AttrDef.Name));
+ IF (Attr = NIL) AND (AttrDef.Value <> '') THEN BEGIN
+ Attr := TAttr.Create (AttrDef.Name, AttrDef.Value);
+ Attr.ValueType := vtDefault;
+ CurAttr.Add (Attr);
+ END;
+ IF Attr <> NIL THEN BEGIN
+ CASE AttrDef.DefaultType OF
+ adDefault : ;
+ adRequired : ; // -!- It is an error in the document if "Attr.Value" is an empty string
+ adImplied : Attr.ValueType := vtImplied;
+ adFixed : BEGIN
+ Attr.ValueType := vtFixed;
+ Attr.Value := AttrDef.Value;
+ END;
+ END;
+ Attr.AttrType := AttrDef.AttrType;
+ END;
+ END;
+ END;
+
+ // --- Normalize Attribute Values. XmlSpec:
+ // - a character reference is processed by appending the referenced character to the attribute value
+ // - an entity reference is processed by recursively processing the replacement text of the entity
+ // - a whitespace character (#x20, #xD, #xA, #x9) is processed by appending #x20 to the normalized value,
+ // except that only a single #x20 is appended for a "#xD#xA" sequence that is part of an external
+ // parsed entity or the literal entity value of an internal parsed entity
+ // - other characters are processed by appending them to the normalized value
+ // If the declared value is not CDATA, then the XML processor must further process the
+ // normalized attribute value by discarding any leading and trailing space (#x20) characters,
+ // and by replacing sequences of space (#x20) characters by a single space (#x20) character.
+ // All attributes for which no declaration has been read should be treated by a
+ // non-validating parser as if declared CDATA.
+ // !!! The XML 1.0 SE specification is somewhat different here
+ // This code does not conform exactly to this specification
+ FOR I := 0 TO CurAttr.Count-1 DO
+ WITH TAttr (CurAttr [I]) DO BEGIN
+ ReplaceGeneralEntities (Value);
+ ReplaceCharacterEntities (Value);
+ IF (AttrType <> atCData) AND (AttrType <> atUnknown)
+ THEN Value := TranslateEncoding (TrimWs (ConvertWs (Value, TRUE)))
+ ELSE Value := TranslateEncoding (ConvertWs (Value, FALSE));
+ END;
+ END;
+END;
+
+
+PROCEDURE TXmlParser.AnalyzeCData;
+ // Analyze CDATA Sections
+BEGIN
+ CurPartType := ptCData;
+ CurFinal := StrPos (CurStart, CDEnd);
+ IF CurFinal = NIL THEN BEGIN
+ CurFinal := StrEnd (CurStart)-1;
+ CurContent := TranslateEncoding (StrPas (CurStart+Length (CDStart)));
+ END
+ ELSE BEGIN
+ SetStringSF (CurContent, CurStart+Length (CDStart), CurFinal-1);
+ INC (CurFinal, Length (CDEnd)-1);
+ CurContent := TranslateEncoding (CurContent);
+ END;
+END;
+
+
+PROCEDURE TXmlParser.AnalyzeText (VAR IsDone : BOOLEAN);
+ (* Analyzes Text Content between Tags. CurFinal will point to the last content character.
+ Content ends at a '<' character or at the end of the document.
+ Entity References and Character Entity references are resolved.
+ If PackSpaces is TRUE, contiguous Whitespace Characters will be compressed to
+ one Space #x20 character, Whitespace at the beginning and end of content will
+ be trimmed off and content which is or becomes empty is not returned to
+ the application (in this case, "IsDone" is set to FALSE which causes the
+ Scan method to proceed directly to the next part. *)
+
+ PROCEDURE ProcessEntity;
+ (* Is called if there is an ampsersand '&' character found in the document.
+ IN "CurFinal" points to the ampersand
+ OUT "CurFinal" points to the first character after the semi-colon ';' *)
+ VAR
+ P : PChar;
+ Name : STRING;
+ EntityDef : TEntityDef;
+ ExternalEntity : TXmlParser;
+ BEGIN
+ P := StrScan (CurFinal , ';');
+ IF P <> NIL THEN BEGIN
+ SetStringSF (Name, CurFinal+1, P-1);
+
+ // Is it a Character Entity?
+ IF (CurFinal+1)^ = '#' THEN BEGIN
+ IF UpCase ((CurFinal+2)^) = 'X' // !!! Can't use "CHR" for Unicode characters > 255:
+ THEN CurContent := CurContent + CHR (StrToIntDef ('$'+Copy (Name, 3, MaxInt), 32))
+ ELSE CurContent := CurContent + CHR (StrToIntDef (Copy (Name, 2, MaxInt), 32));
+ CurFinal := P+1;
+ EXIT;
+ END
+
+ // Is it a Predefined Entity?
+ ELSE IF Name = 'lt' THEN BEGIN CurContent := CurContent + '<'; CurFinal := P+1; EXIT; END
+ ELSE IF Name = 'gt' THEN BEGIN CurContent := CurContent + '>'; CurFinal := P+1; EXIT; END
+ ELSE IF Name = 'amp' THEN BEGIN CurContent := CurContent + '&'; CurFinal := P+1; EXIT; END
+ ELSE IF Name = 'apos' THEN BEGIN CurContent := CurContent + ''''; CurFinal := P+1; EXIT; END
+ ELSE IF Name = 'quot' THEN BEGIN CurContent := CurContent + '"'; CurFinal := P+1; EXIT; END;
+
+ // Replace with Entity from DTD
+ EntityDef := TEntityDef (Entities.Node (Name));
+ IF EntityDef <> NIL THEN BEGIN
+ IF EntityDef.Value <> '' THEN BEGIN
+ EntityStack.Push (P+1);
+ CurFinal := PChar (EntityDef.Value);
+ END
+ ELSE BEGIN
+ ExternalEntity := LoadExternalEntity (EntityDef.SystemId, EntityDef.PublicId, EntityDef.NotationName);
+ EntityStack.Push (ExternalEntity, P+1);
+ CurFinal := ExternalEntity.DocBuffer;
+ END;
+ END
+ ELSE BEGIN
+ CurContent := CurContent + Name;
+ CurFinal := P+1;
+ END;
+ END
+ ELSE BEGIN
+ INC (CurFinal);
+ END;
+ END;
+
+VAR
+ C : INTEGER;
+BEGIN
+ CurFinal := CurStart;
+ CurPartType := ptContent;
+ CurContent := '';
+ C := 0;
+ REPEAT
+ CASE CurFinal^ OF
+ '&' : BEGIN
+ CurContent := CurContent + TranslateEncoding (StrLPas (CurFinal-C, C));
+ C := 0;
+ ProcessEntity;
+ CONTINUE;
+ END;
+ #0 : BEGIN
+ IF EntityStack.Count = 0 THEN
+ BREAK
+ ELSE BEGIN
+ CurContent := CurContent + TranslateEncoding (StrLPas (CurFinal-C, C));
+ C := 0;
+ CurFinal := EntityStack.Pop;
+ CONTINUE;
+ END;
+ END;
+ '<' : BREAK;
+ ELSE INC (C);
+ END;
+ INC (CurFinal);
+ UNTIL FALSE;
+ CurContent := CurContent + TranslateEncoding (StrLPas (CurFinal-C, C));
+ DEC (CurFinal);
+
+ IF FNormalize THEN BEGIN
+ CurContent := ConvertWs (TrimWs (CurContent), TRUE);
+ IsDone := CurContent <> ''; // IsDone will only get FALSE if PackSpaces is TRUE
+ END;
+END;
+
+
+PROCEDURE TXmlParser.AnalyzeElementDecl (Start : PChar; VAR Final : PChar);
+ (* Parse <!ELEMENT declaration starting at "Start"
+ Final must point to the terminating '>' character
+ XmlSpec 3.2:
+ elementdecl ::= '<!ELEMENT' S Name S contentspec S? '>'
+ contentspec ::= 'EMPTY' | 'ANY' | Mixed | children
+ Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*' |
+ '(' S? '#PCDATA' S? ')'
+ children ::= (choice | seq) ('?' | '*' | '+')?
+ choice ::= '(' S? cp ( S? '|' S? cp )* S? ')'
+ cp ::= (Name | choice | seq) ('?' | '*' | '+')?
+ seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
+
+ More simply:
+ contentspec ::= EMPTY
+ ANY
+ '(#PCDATA)'
+ '(#PCDATA | A | B)*'
+ '(A, B, C)'
+ '(A | B | C)'
+ '(A?, B*, C+),
+ '(A, (B | C | D)* )' *)
+VAR
+ Element : TElemDef;
+ Elem2 : TElemDef;
+ F : PChar;
+ DER : TDtdElementRec;
+BEGIN
+ Element := TElemDef.Create;
+ Final := Start + 9;
+ DER.Start := Start;
+ REPEAT
+ IF Final^ = '>' THEN BREAK;
+ IF (Final^ IN CNameStart) AND (Element.Name = '') THEN BEGIN
+ ExtractName (Final, CWhitespace, F);
+ SetStringSF (Element.Name, Final, F);
+ Final := F;
+ F := StrScan (Final+1, '>');
+ IF F = NIL THEN BEGIN
+ Element.Definition := STRING (Final);
+ Final := StrEnd (Final);
+ BREAK;
+ END
+ ELSE BEGIN
+ SetStringSF (Element.Definition, Final+1, F-1);
+ Final := F;
+ BREAK;
+ END;
+ END;
+ INC (Final);
+ UNTIL FALSE;
+ Element.Definition := DelChars (Element.Definition, CWhitespace);
+ ReplaceParameterEntities (Element.Definition);
+ IF Element.Definition = 'EMPTY' THEN Element.ElemType := etEmpty
+ ELSE IF Element.Definition = 'ANY' THEN Element.ElemType := etAny
+ ELSE IF Copy (Element.Definition, 1, 8) = '(#PCDATA' THEN Element.ElemType := etMixed
+ ELSE IF Copy (Element.Definition, 1, 1) = '(' THEN Element.ElemType := etChildren
+ ELSE Element.ElemType := etAny;
+
+ Elem2 := Elements.Node (Element.Name);
+ IF Elem2 <> NIL THEN
+ Elements.Delete (Elements.IndexOf (Elem2));
+ Elements.Add (Element);
+ Final := StrScanE (Final, '>');
+ DER.ElementType := deElement;
+ DER.ElemDef := Element;
+ DER.Final := Final;
+ DtdElementFound (DER);
+END;
+
+
+PROCEDURE TXmlParser.AnalyzeAttListDecl (Start : PChar; VAR Final : PChar);
+ (* Parse <!ATTLIST declaration starting at "Start"
+ Final must point to the terminating '>' character
+ XmlSpec 3.3:
+ AttlistDecl ::= '<!ATTLIST' S Name AttDef* S? '>'
+ AttDef ::= S Name S AttType S DefaultDecl
+ AttType ::= StringType | TokenizedType | EnumeratedType
+ StringType ::= 'CDATA'
+ TokenizedType ::= 'ID' | 'IDREF' | 'IDREFS' | 'ENTITY' | 'ENTITIES' | 'NMTOKEN' | 'NMTOKENS'
+ EnumeratedType ::= NotationType | Enumeration
+ NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
+ Enumeration ::= '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')'
+ DefaultDecl ::= '#REQUIRED' | '#IMPLIED' | (('#FIXED' S)? AttValue)
+ AttValue ::= '"' ([^<&"] | Reference)* '"' | "'" ([^<&'] | Reference)* "'"
+ Examples:
+ <!ATTLIST address
+ A1 CDATA "Default"
+ A2 ID #REQUIRED
+ A3 IDREF #IMPLIED
+ A4 IDREFS #IMPLIED
+ A5 ENTITY #FIXED "&at;&#252;"
+ A6 ENTITIES #REQUIRED
+ A7 NOTATION (WMF | DXF) "WMF"
+ A8 (A | B | C) #REQUIRED> *)
+TYPE
+ TPhase = (phElementName, phName, phType, phNotationContent, phDefault);
+VAR
+ Phase : TPhase;
+ F : PChar;
+ ElementName : STRING;
+ ElemDef : TElemDef;
+ AttrDef : TAttrDef;
+ AttrDef2 : TAttrDef;
+ Strg : STRING;
+ DER : TDtdElementRec;
+BEGIN
+ Final := Start + 9; // The character after <!ATTLIST
+ Phase := phElementName;
+ DER.Start := Start;
+ AttrDef := NIL;
+ ElemDef := NIL;
+ REPEAT
+ IF NOT (Final^ IN CWhitespace) THEN
+ CASE Final^ OF
+ '%' : BEGIN
+ PushPE (Final);
+ CONTINUE;
+ END;
+ #0 : IF EntityStack.Count = 0 THEN
+ BREAK
+ ELSE BEGIN
+ Final := EntityStack.Pop;
+ CONTINUE;
+ END;
+ '>' : BREAK;
+ ELSE CASE Phase OF
+ phElementName : BEGIN
+ ExtractName (Final, CWhitespace + CQuoteChar + ['#'], F);
+ SetStringSF (ElementName, Final, F);
+ Final := F;
+ ElemDef := Elements.Node (ElementName);
+ IF ElemDef = NIL THEN BEGIN
+ ElemDef := TElemDef.Create;
+ ElemDef.Name := ElementName;
+ ElemDef.Definition := 'ANY';
+ ElemDef.ElemType := etAny;
+ Elements.Add (ElemDef);
+ END;
+ Phase := phName;
+ END;
+ phName : BEGIN
+ AttrDef := TAttrDef.Create;
+ ExtractName (Final, CWhitespace + CQuoteChar + ['#'], F);
+ SetStringSF (AttrDef.Name, Final, F);
+ Final := F;
+ AttrDef2 := TAttrDef (ElemDef.Node (AttrDef.Name));
+ IF AttrDef2 <> NIL THEN
+ ElemDef.Delete (ElemDef.IndexOf (AttrDef2));
+ ElemDef.Add (AttrDef);
+ Phase := phType;
+ END;
+ phType : BEGIN
+ IF Final^ = '(' THEN BEGIN
+ F := StrScan (Final+1, ')');
+ IF F <> NIL
+ THEN SetStringSF (AttrDef.TypeDef, Final+1, F-1)
+ ELSE AttrDef.TypeDef := STRING (Final+1);
+ AttrDef.TypeDef := DelChars (AttrDef.TypeDef, CWhitespace);
+ AttrDef.AttrType := atEnumeration;
+ ReplaceParameterEntities (AttrDef.TypeDef);
+ ReplaceCharacterEntities (AttrDef.TypeDef);
+ Phase := phDefault;
+ END
+ ELSE IF StrLComp (Final, 'NOTATION', 8) = 0 THEN BEGIN
+ INC (Final, 8);
+ AttrDef.AttrType := atNotation;
+ Phase := phNotationContent;
+ END
+ ELSE BEGIN
+ ExtractName (Final, CWhitespace+CQuoteChar+['#'], F);
+ SetStringSF (AttrDef.TypeDef, Final, F);
+ IF AttrDef.TypeDef = 'CDATA' THEN AttrDef.AttrType := atCData
+ ELSE IF AttrDef.TypeDef = 'ID' THEN AttrDef.AttrType := atId
+ ELSE IF AttrDef.TypeDef = 'IDREF' THEN AttrDef.AttrType := atIdRef
+ ELSE IF AttrDef.TypeDef = 'IDREFS' THEN AttrDef.AttrType := atIdRefs
+ ELSE IF AttrDef.TypeDef = 'ENTITY' THEN AttrDef.AttrType := atEntity
+ ELSE IF AttrDef.TypeDef = 'ENTITIES' THEN AttrDef.AttrType := atEntities
+ ELSE IF AttrDef.TypeDef = 'NMTOKEN' THEN AttrDef.AttrType := atNmToken
+ ELSE IF AttrDef.TypeDef = 'NMTOKENS' THEN AttrDef.AttrType := atNmTokens;
+ Phase := phDefault;
+ END
+ END;
+ phNotationContent : BEGIN
+ F := StrScan (Final, ')');
+ IF F <> NIL THEN
+ SetStringSF (AttrDef.Notations, Final+1, F-1)
+ ELSE BEGIN
+ AttrDef.Notations := STRING (Final+1);
+ Final := StrEnd (Final);
+ END;
+ ReplaceParameterEntities (AttrDef.Notations);
+ AttrDef.Notations := DelChars (AttrDef.Notations, CWhitespace);
+ Phase := phDefault;
+ END;
+ phDefault : BEGIN
+ IF Final^ = '#' THEN BEGIN
+ ExtractName (Final, CWhiteSpace + CQuoteChar, F);
+ SetStringSF (Strg, Final, F);
+ Final := F;
+ ReplaceParameterEntities (Strg);
+ IF Strg = '#REQUIRED' THEN BEGIN AttrDef.DefaultType := adRequired; Phase := phName; END
+ ELSE IF Strg = '#IMPLIED' THEN BEGIN AttrDef.DefaultType := adImplied; Phase := phName; END
+ ELSE IF Strg = '#FIXED' THEN AttrDef.DefaultType := adFixed;
+ END
+ ELSE IF (Final^ IN CQuoteChar) THEN BEGIN
+ ExtractQuote (Final, AttrDef.Value, Final);
+ ReplaceParameterEntities (AttrDef.Value);
+ ReplaceCharacterEntities (AttrDef.Value);
+ Phase := phName;
+ END;
+ IF Phase = phName THEN BEGIN
+ AttrDef := NIL;
+ END;
+ END;
+
+ END;
+ END;
+ INC (Final);
+ UNTIL FALSE;
+
+ Final := StrScan (Final, '>');
+
+ DER.ElementType := deAttList;
+ DER.ElemDef := ElemDef;
+ DER.Final := Final;
+ DtdElementFound (DER);
+END;
+
+
+PROCEDURE TXmlParser.AnalyzeEntityDecl (Start : PChar; VAR Final : PChar);
+ (* Parse <!ENTITY declaration starting at "Start"
+ Final must point to the terminating '>' character
+ XmlSpec 4.2:
+ EntityDecl ::= '<!ENTITY' S Name S EntityDef S? '>' |
+ '<!ENTITY' S '%' S Name S PEDef S? '>'
+ EntityDef ::= EntityValue | (ExternalID NDataDecl?)
+ PEDef ::= EntityValue | ExternalID
+ NDataDecl ::= S 'NDATA' S Name
+ EntityValue ::= '"' ([^%&"] | PEReference | EntityRef | CharRef)* '"' |
+ "'" ([^%&'] | PEReference | EntityRef | CharRef)* "'"
+ PEReference ::= '%' Name ';'
+
+ Examples
+ <!ENTITY test1 "Stefan Heymann"> <!-- Internal, general, parsed -->
+ <!ENTITY test2 SYSTEM "ent2.xml"> <!-- External, general, parsed -->
+ <!ENTITY test2 SYSTEM "ent3.gif" NDATA gif> <!-- External, general, unparsed -->
+ <!ENTITY % test3 "<!ELEMENT q ANY>"> <!-- Internal, parameter -->
+ <!ENTITY % test6 SYSTEM "ent6.xml"> <!-- External, parameter -->
+ <!ENTITY test4 "&test1; ist lieb"> <!-- IGP, Replacement text <> literal value -->
+ <!ENTITY test5 "<p>Dies ist ein Test-Absatz</p>"> <!-- IGP, See XmlSpec 2.4 -->
+ *)
+TYPE
+ TPhase = (phName, phContent, phNData, phNotationName, phFinalGT);
+VAR
+ Phase : TPhase;
+ IsParamEntity : BOOLEAN;
+ F : PChar;
+ ExternalID : TExternalID;
+ EntityDef : TEntityDef;
+ EntityDef2 : TEntityDef;
+ DER : TDtdElementRec;
+BEGIN
+ Final := Start + 8; // First char after <!ENTITY
+ DER.Start := Start;
+ Phase := phName;
+ IsParamEntity := FALSE;
+ EntityDef := TEntityDef.Create;
+ REPEAT
+ IF NOT (Final^ IN CWhitespace) THEN
+ CASE Final^ OF
+ '%' : IsParamEntity := TRUE;
+ '>' : BREAK;
+ ELSE CASE Phase OF
+ phName : IF Final^ IN CNameStart THEN BEGIN
+ ExtractName (Final, CWhitespace + CQuoteChar, F);
+ SetStringSF (EntityDef.Name, Final, F);
+ Final := F;
+ Phase := phContent;
+ END;
+ phContent : IF Final^ IN CQuoteChar THEN BEGIN
+ ExtractQuote (Final, EntityDef.Value, Final);
+ Phase := phFinalGT;
+ END
+ ELSE IF (StrLComp (Final, 'SYSTEM', 6) = 0) OR
+ (StrLComp (Final, 'PUBLIC', 6) = 0) THEN BEGIN
+ ExternalID := TExternalID.Create (Final);
+ EntityDef.SystemId := ExternalID.SystemId;
+ EntityDef.PublicId := ExternalID.PublicId;
+ Final := ExternalID.Final;
+ Phase := phNData;
+ ExternalID.Free;
+ END;
+ phNData : IF StrLComp (Final, 'NDATA', 5) = 0 THEN BEGIN
+ INC (Final, 4);
+ Phase := phNotationName;
+ END;
+ phNotationName : IF Final^ IN CNameStart THEN BEGIN
+ ExtractName (Final, CWhitespace + ['>'], F);
+ SetStringSF (EntityDef.NotationName, Final, F);
+ Final := F;
+ Phase := phFinalGT;
+ END;
+ phFinalGT : ; // -!- There is an error in the document if this branch is called
+ END;
+ END;
+ INC (Final);
+ UNTIL FALSE;
+ IF IsParamEntity THEN BEGIN
+ EntityDef2 := TEntityDef (ParEntities.Node (EntityDef.Name));
+ IF EntityDef2 <> NIL THEN
+ ParEntities.Delete (ParEntities.IndexOf (EntityDef2));
+ ParEntities.Add (EntityDef);
+ ReplaceCharacterEntities (EntityDef.Value);
+ END
+ ELSE BEGIN
+ EntityDef2 := TEntityDef (Entities.Node (EntityDef.Name));
+ IF EntityDef2 <> NIL THEN
+ Entities.Delete (Entities.IndexOf (EntityDef2));
+ Entities.Add (EntityDef);
+ ReplaceParameterEntities (EntityDef.Value); // Create replacement texts (see XmlSpec 4.5)
+ ReplaceCharacterEntities (EntityDef.Value);
+ END;
+ Final := StrScanE (Final, '>');
+
+ DER.ElementType := deEntity;
+ DER.EntityDef := EntityDef;
+ DER.Final := Final;
+ DtdElementFound (DER);
+END;
+
+
+PROCEDURE TXmlParser.AnalyzeNotationDecl (Start : PChar; VAR Final : PChar);
+ // Parse <!NOTATION declaration starting at "Start"
+ // Final must point to the terminating '>' character
+ // XmlSpec 4.7: NotationDecl ::= '<!NOTATION' S Name S (ExternalID | PublicID) S? '>'
+TYPE
+ TPhase = (phName, phExtId, phEnd);
+VAR
+ ExternalID : TExternalID;
+ Phase : TPhase;
+ F : PChar;
+ NotationDef : TNotationDef;
+ DER : TDtdElementRec;
+BEGIN
+ Final := Start + 10; // Character after <!NOTATION
+ DER.Start := Start;
+ Phase := phName;
+ NotationDef := TNotationDef.Create;
+ REPEAT
+ IF NOT (Final^ IN CWhitespace) THEN
+ CASE Final^ OF
+ '>',
+ #0 : BREAK;
+ ELSE CASE Phase OF
+ phName : BEGIN
+ ExtractName (Final, CWhitespace + ['>'], F);
+ SetStringSF (NotationDef.Name, Final, F);
+ Final := F;
+ Phase := phExtId;
+ END;
+ phExtId : BEGIN
+ ExternalID := TExternalID.Create (Final);
+ NotationDef.Value := ExternalID.SystemId;
+ NotationDef.PublicId := ExternalID.PublicId;
+ Final := ExternalId.Final;
+ ExternalId.Free;
+ Phase := phEnd;
+ END;
+ phEnd : ; // -!- There is an error in the document if this branch is called
+ END;
+ END;
+ INC (Final);
+ UNTIL FALSE;
+ Notations.Add (NotationDef);
+ Final := StrScanE (Final, '>');
+
+ DER.ElementType := deNotation;
+ DER.NotationDef := NotationDef;
+ DER.Final := Final;
+ DtdElementFound (DER);
+END;
+
+
+PROCEDURE TXmlParser.PushPE (VAR Start : PChar);
+ (* If there is a parameter entity reference found in the data stream,
+ the current position will be pushed to the entity stack.
+ Start: IN Pointer to the '%' character starting the PE reference
+ OUT Pointer to first character of PE replacement text *)
+VAR
+ P : PChar;
+ EntityDef : TEntityDef;
+BEGIN
+ P := StrScan (Start, ';');
+ IF P <> NIL THEN BEGIN
+ EntityDef := TEntityDef (ParEntities.Node (StrSFPas (Start+1, P-1)));
+ IF EntityDef <> NIL THEN BEGIN
+ EntityStack.Push (P+1);
+ Start := PChar (EntityDef.Value);
+ END
+ ELSE
+ Start := P+1;
+ END;
+END;
+
+
+PROCEDURE TXmlParser.ReplaceCharacterEntities (VAR Str : STRING);
+ // Replaces all Character Entity References in the String
+VAR
+ Start : INTEGER;
+ PAmp : PChar;
+ PSemi : PChar;
+ PosAmp : INTEGER;
+ Len : INTEGER; // Length of Entity Reference
+BEGIN
+ IF Str = '' THEN EXIT;
+ Start := 1;
+ REPEAT
+ PAmp := StrPos (PChar (Str) + Start-1, '&#');
+ IF PAmp = NIL THEN BREAK;
+ PSemi := StrScan (PAmp+2, ';');
+ IF PSemi = NIL THEN BREAK;
+ PosAmp := PAmp - PChar (Str) + 1;
+ Len := PSemi-PAmp+1;
+ IF CompareText (Str [PosAmp+2], 'x') = 0 // !!! Can't use "CHR" for Unicode characters > 255
+ THEN Str [PosAmp] := CHR (StrToIntDef ('$'+Copy (Str, PosAmp+3, Len-4), 0))
+ ELSE Str [PosAmp] := CHR (StrToIntDef (Copy (Str, PosAmp+2, Len-3), 32));
+ Delete (Str, PosAmp+1, Len-1);
+ Start := PosAmp + 1;
+ UNTIL FALSE;
+END;
+
+
+PROCEDURE TXmlParser.ReplaceParameterEntities (VAR Str : STRING);
+ // Recursively replaces all Parameter Entity References in the String
+ PROCEDURE ReplaceEntities (VAR Str : STRING);
+ VAR
+ Start : INTEGER;
+ PAmp : PChar;
+ PSemi : PChar;
+ PosAmp : INTEGER;
+ Len : INTEGER;
+ Entity : TEntityDef;
+ Repl : STRING; // Replacement
+ BEGIN
+ IF Str = '' THEN EXIT;
+ Start := 1;
+ REPEAT
+ PAmp := StrPos (PChar (Str)+Start-1, '%');
+ IF PAmp = NIL THEN BREAK;
+ PSemi := StrScan (PAmp+2, ';');
+ IF PSemi = NIL THEN BREAK;
+ PosAmp := PAmp - PChar (Str) + 1;
+ Len := PSemi-PAmp+1;
+ Entity := TEntityDef (ParEntities.Node (Copy (Str, PosAmp+1, Len-2)));
+ IF Entity <> NIL THEN BEGIN
+ Repl := Entity.Value;
+ ReplaceEntities (Repl); // Recursion
+ END
+ ELSE
+ Repl := Copy (Str, PosAmp, Len);
+ Delete (Str, PosAmp, Len);
+ Insert (Repl, Str, PosAmp);
+ Start := PosAmp + Length (Repl);
+ UNTIL FALSE;
+ END;
+BEGIN
+ ReplaceEntities (Str);
+END;
+
+
+PROCEDURE TXmlParser.ReplaceGeneralEntities (VAR Str : STRING);
+ // Recursively replaces General Entity References in the String
+ PROCEDURE ReplaceEntities (VAR Str : STRING);
+ VAR
+ Start : INTEGER;
+ PAmp : PChar;
+ PSemi : PChar;
+ PosAmp : INTEGER;
+ Len : INTEGER;
+ EntityDef : TEntityDef;
+ EntName : STRING;
+ Repl : STRING; // Replacement
+ ExternalEntity : TXmlParser;
+ BEGIN
+ IF Str = '' THEN EXIT;
+ Start := 1;
+ REPEAT
+ PAmp := StrPos (PChar (Str)+Start-1, '&');
+ IF PAmp = NIL THEN BREAK;
+ PSemi := StrScan (PAmp+2, ';');
+ IF PSemi = NIL THEN BREAK;
+ PosAmp := PAmp - PChar (Str) + 1;
+ Len := PSemi-PAmp+1;
+ EntName := Copy (Str, PosAmp+1, Len-2);
+ IF EntName = 'lt' THEN Repl := '<'
+ ELSE IF EntName = 'gt' THEN Repl := '>'
+ ELSE IF EntName = 'amp' THEN Repl := '&'
+ ELSE IF EntName = 'apos' THEN Repl := ''''
+ ELSE IF EntName = 'quot' THEN Repl := '"'
+ ELSE BEGIN
+ EntityDef := TEntityDef (Entities.Node (EntName));
+ IF EntityDef <> NIL THEN BEGIN
+ IF EntityDef.Value <> '' THEN // Internal Entity
+ Repl := EntityDef.Value
+ ELSE BEGIN // External Entity
+ ExternalEntity := LoadExternalEntity (EntityDef.SystemId, EntityDef.PublicId, EntityDef.NotationName);
+ Repl := StrPas (ExternalEntity.DocBuffer); // !!! What if it contains a Text Declaration?
+ ExternalEntity.Free;
+ END;
+ ReplaceEntities (Repl); // Recursion
+ END
+ ELSE
+ Repl := Copy (Str, PosAmp, Len);
+ END;
+ Delete (Str, PosAmp, Len);
+ Insert (Repl, Str, PosAmp);
+ Start := PosAmp + Length (Repl);
+ UNTIL FALSE;
+ END;
+BEGIN
+ ReplaceEntities (Str);
+END;
+
+
+FUNCTION TXmlParser.LoadExternalEntity (SystemId, PublicId, Notation : STRING) : TXmlParser;
+ // This will be called whenever there is a Parsed External Entity or
+ // the DTD External Subset to be parsed.
+ // It has to create a TXmlParser instance and load the desired Entity.
+ // This instance of LoadExternalEntity assumes that "SystemId" is a valid
+ // file name (relative to the Document source) and loads this file using
+ // the LoadFromFile method.
+VAR
+ Filename : STRING;
+BEGIN
+ // --- Convert System ID to complete filename
+ Filename := StringReplace (SystemId, '/', '\', [rfReplaceAll]);
+ IF Copy (FSource, 1, 1) <> '<' THEN
+ IF (Copy (Filename, 1, 2) = '\\') OR (Copy (Filename, 2, 1) = ':') THEN
+ // Already has an absolute Path
+ ELSE BEGIN
+ Filename := ExtractFilePath (FSource) + Filename;
+ END;
+
+ // --- Load the File
+ Result := TXmlParser.Create;
+ Result.LoadFromFile (Filename);
+END;
+
+
+FUNCTION TXmlParser.TranslateEncoding (CONST Source : STRING) : STRING;
+ // The member variable "CurEncoding" always holds the name of the current
+ // encoding, e.g. 'UTF-8' or 'ISO-8859-1'.
+ // This virtual method "TranslateEncoding" is responsible for translating
+ // the content passed in the "Source" parameter to the Encoding which
+ // is expected by the application.
+ // This instance of "TranlateEncoding" assumes that the Application expects
+ // Windows ANSI (Win1252) strings. It is able to transform UTF-8 or ISO-8859-1
+ // encodings.
+ // If you want your application to understand or create other encodings, you
+ // override this function.
+BEGIN
+ IF CurEncoding = 'UTF-8'
+ THEN Result := Utf8ToAnsi (Source)
+ ELSE Result := Source;
+END;
+
+
+PROCEDURE TXmlParser.DtdElementFound (DtdElementRec : TDtdElementRec);
+ // This method is called for every element which is found in the DTD
+ // declaration. The variant record TDtdElementRec is passed which
+ // holds informations about the element.
+ // You can override this function to handle DTD declarations.
+ // Note that when you parse the same Document instance a second time,
+ // the DTD will not get parsed again.
+BEGIN
+END;
+
+
+FUNCTION TXmlParser.GetDocBuffer: PChar;
+ // Returns FBuffer or a pointer to a NUL char if Buffer is empty
+BEGIN
+ IF FBuffer = NIL
+ THEN Result := #0
+ ELSE Result := FBuffer;
+END;
+
+
+(*$IFNDEF HAS_CONTNRS_UNIT
+===============================================================================================
+TObjectList
+===============================================================================================
+*)
+
+DESTRUCTOR TObjectList.Destroy;
+BEGIN
+ Clear;
+ SetCapacity(0);
+ INHERITED Destroy;
+END;
+
+
+PROCEDURE TObjectList.Delete (Index : INTEGER);
+BEGIN
+ IF (Index < 0) OR (Index >= Count) THEN EXIT;
+ TObject (Items [Index]).Free;
+ INHERITED Delete (Index);
+END;
+
+
+PROCEDURE TObjectList.Clear;
+BEGIN
+ WHILE Count > 0 DO
+ Delete (Count-1);
+END;
+
+(*$ENDIF *)
+
+(*
+===============================================================================================
+TNvpNode
+--------
+Node base class for the TNvpList
+===============================================================================================
+*)
+
+CONSTRUCTOR TNvpNode.Create (TheName, TheValue : STRING);
+BEGIN
+ INHERITED Create;
+ Name := TheName;
+ Value := TheValue;
+END;
+
+
+(*
+===============================================================================================
+TNvpList
+--------
+A generic List of Name-Value Pairs, based on the TObjectList introduced in Delphi 5
+===============================================================================================
+*)
+
+PROCEDURE TNvpList.Add (Node : TNvpNode);
+VAR
+ I : INTEGER;
+BEGIN
+ FOR I := Count-1 DOWNTO 0 DO
+ IF Node.Name > TNvpNode (Items [I]).Name THEN BEGIN
+ Insert (I+1, Node);
+ EXIT;
+ END;
+ Insert (0, Node);
+END;
+
+
+
+FUNCTION TNvpList.Node (Name : STRING) : TNvpNode;
+ // Binary search for Node
+VAR
+ L, H : INTEGER; // Low, High Limit
+ T, C : INTEGER; // Test Index, Comparison result
+ Last : INTEGER; // Last Test Index
+BEGIN
+ IF Count=0 THEN BEGIN
+ Result := NIL;
+ EXIT;
+ END;
+
+ L := 0;
+ H := Count;
+ Last := -1;
+ REPEAT
+ T := (L+H) DIV 2;
+ IF T=Last THEN BREAK;
+ Result := TNvpNode (Items [T]);
+ C := CompareStr (Result.Name, Name);
+ IF C = 0 THEN EXIT
+ ELSE IF C < 0 THEN L := T
+ ELSE H := T;
+ Last := T;
+ UNTIL FALSE;
+ Result := NIL;
+END;
+
+
+FUNCTION TNvpList.Node (Index : INTEGER) : TNvpNode;
+BEGIN
+ IF (Index < 0) OR (Index >= Count)
+ THEN Result := NIL
+ ELSE Result := TNvpNode (Items [Index]);
+END;
+
+
+FUNCTION TNvpList.Value (Name : STRING) : STRING;
+VAR
+ Nvp : TNvpNode;
+BEGIN
+ Nvp := TNvpNode (Node (Name));
+ IF Nvp <> NIL
+ THEN Result := Nvp.Value
+ ELSE Result := '';
+END;
+
+
+FUNCTION TNvpList.Value (Index : INTEGER) : STRING;
+BEGIN
+ IF (Index < 0) OR (Index >= Count)
+ THEN Result := ''
+ ELSE Result := TNvpNode (Items [Index]).Value;
+END;
+
+
+FUNCTION TNvpList.Name (Index : INTEGER) : STRING;
+BEGIN
+ IF (Index < 0) OR (Index >= Count)
+ THEN Result := ''
+ ELSE Result := TNvpNode (Items [Index]).Name;
+END;
+
+
+(*
+===============================================================================================
+TAttrList
+List of Attributes. The "Analyze" method extracts the Attributes from the given Buffer.
+Is used for extraction of Attributes in Start-Tags, Empty-Element Tags and the "pseudo"
+attributes in XML Prologs, Text Declarations and PIs.
+===============================================================================================
+*)
+
+PROCEDURE TAttrList.Analyze (Start : PChar; VAR Final : PChar);
+ // Analyze the Buffer for Attribute=Name pairs.
+ // Terminates when there is a character which is not IN CNameStart
+ // (e.g. '?>' or '>' or '/>')
+TYPE
+ TPhase = (phName, phEq, phValue);
+VAR
+ Phase : TPhase;
+ F : PChar;
+ Name : STRING;
+ Value : STRING;
+ Attr : TAttr;
+BEGIN
+ Clear;
+ Phase := phName;
+ Final := Start;
+ REPEAT
+ IF (Final^ = #0) OR (Final^ = '>') THEN BREAK;
+ IF NOT (Final^ IN CWhitespace) THEN
+ CASE Phase OF
+ phName : BEGIN
+ IF NOT (Final^ IN CNameStart) THEN EXIT;
+ ExtractName (Final, CWhitespace + ['=', '/'], F);
+ SetStringSF (Name, Final, F);
+ Final := F;
+ Phase := phEq;
+ END;
+ phEq : BEGIN
+ IF Final^ = '=' THEN
+ Phase := phValue
+ END;
+ phValue : BEGIN
+ IF Final^ IN CQuoteChar THEN BEGIN
+ ExtractQuote (Final, Value, F);
+ Attr := TAttr.Create;
+ Attr.Name := Name;
+ Attr.Value := Value;
+ Attr.ValueType := vtNormal;
+ Add (Attr);
+ Final := F;
+ Phase := phName;
+ END;
+ END;
+ END;
+ INC (Final);
+ UNTIL FALSE;
+END;
+
+
+(*
+===============================================================================================
+TElemList
+List of TElemDef nodes.
+===============================================================================================
+*)
+
+FUNCTION TElemList.Node (Name : STRING) : TElemDef;
+ // Binary search for the Node with the given Name
+VAR
+ L, H : INTEGER; // Low, High Limit
+ T, C : INTEGER; // Test Index, Comparison result
+ Last : INTEGER; // Last Test Index
+BEGIN
+ IF Count=0 THEN BEGIN
+ Result := NIL;
+ EXIT;
+ END;
+
+ L := 0;
+ H := Count;
+ Last := -1;
+ REPEAT
+ T := (L+H) DIV 2;
+ IF T=Last THEN BREAK;
+ Result := TElemDef (Items [T]);
+ C := CompareStr (Result.Name, Name);
+ IF C = 0 THEN EXIT
+ ELSE IF C < 0 THEN L := T
+ ELSE H := T;
+ Last := T;
+ UNTIL FALSE;
+ Result := NIL;
+END;
+
+
+PROCEDURE TElemList.Add (Node : TElemDef);
+VAR
+ I : INTEGER;
+BEGIN
+ FOR I := Count-1 DOWNTO 0 DO
+ IF Node.Name > TElemDef (Items [I]).Name THEN BEGIN
+ Insert (I+1, Node);
+ EXIT;
+ END;
+ Insert (0, Node);
+END;
+
+
+(*
+===============================================================================================
+TScannerXmlParser
+A TXmlParser descendant for the TCustomXmlScanner component
+===============================================================================================
+*)
+
+TYPE
+ TScannerXmlParser = CLASS (TXmlParser)
+ Scanner : TCustomXmlScanner;
+ CONSTRUCTOR Create (TheScanner : TCustomXmlScanner);
+ FUNCTION LoadExternalEntity (SystemId, PublicId,
+ Notation : STRING) : TXmlParser; OVERRIDE;
+ FUNCTION TranslateEncoding (CONST Source : STRING) : STRING; OVERRIDE;
+ PROCEDURE DtdElementFound (DtdElementRec : TDtdElementRec); OVERRIDE;
+ END;
+
+CONSTRUCTOR TScannerXmlParser.Create (TheScanner : TCustomXmlScanner);
+BEGIN
+ INHERITED Create;
+ Scanner := TheScanner;
+END;
+
+
+FUNCTION TScannerXmlParser.LoadExternalEntity (SystemId, PublicId, Notation : STRING) : TXmlParser;
+BEGIN
+ IF Assigned (Scanner.FOnLoadExternal)
+ THEN Scanner.FOnLoadExternal (Scanner, SystemId, PublicId, Notation, Result)
+ ELSE Result := INHERITED LoadExternalEntity (SystemId, PublicId, Notation);
+END;
+
+
+FUNCTION TScannerXmlParser.TranslateEncoding (CONST Source : STRING) : STRING;
+BEGIN
+ IF Assigned (Scanner.FOnTranslateEncoding)
+ THEN Result := Scanner.FOnTranslateEncoding (Scanner, CurEncoding, Source)
+ ELSE Result := INHERITED TranslateEncoding (Source);
+END;
+
+
+PROCEDURE TScannerXmlParser.DtdElementFound (DtdElementRec : TDtdElementRec);
+BEGIN
+ WITH DtdElementRec DO
+ CASE ElementType OF
+ deElement : Scanner.WhenElement (ElemDef);
+ deAttList : Scanner.WhenAttList (ElemDef);
+ deEntity : Scanner.WhenEntity (EntityDef);
+ deNotation : Scanner.WhenNotation (NotationDef);
+ dePI : Scanner.WhenPI (STRING (Target), STRING (Content), AttrList);
+ deComment : Scanner.WhenComment (StrSFPas (Start, Final));
+ deError : Scanner.WhenDtdError (Pos);
+ END;
+END;
+
+
+(*
+===============================================================================================
+TCustomXmlScanner
+===============================================================================================
+*)
+
+CONSTRUCTOR TCustomXmlScanner.Create (AOwner: TComponent);
+BEGIN
+ INHERITED;
+ FXmlParser := TScannerXmlParser.Create (Self);
+END;
+
+
+DESTRUCTOR TCustomXmlScanner.Destroy;
+BEGIN
+ FXmlParser.Free;
+ INHERITED;
+END;
+
+
+PROCEDURE TCustomXmlScanner.LoadFromFile (Filename : TFilename);
+ // Load XML Document from file
+BEGIN
+ FXmlParser.LoadFromFile (Filename);
+END;
+
+
+PROCEDURE TCustomXmlScanner.LoadFromBuffer (Buffer : PChar);
+ // Load XML Document from buffer
+BEGIN
+ FXmlParser.LoadFromBuffer (Buffer);
+END;
+
+
+PROCEDURE TCustomXmlScanner.SetBuffer (Buffer : PChar);
+ // Refer to Buffer
+BEGIN
+ FXmlParser.SetBuffer (Buffer);
+END;
+
+
+FUNCTION TCustomXmlScanner.GetFilename : TFilename;
+BEGIN
+ Result := FXmlParser.Source;
+END;
+
+
+FUNCTION TCustomXmlScanner.GetNormalize : BOOLEAN;
+BEGIN
+ Result := FXmlParser.Normalize;
+END;
+
+
+PROCEDURE TCustomXmlScanner.SetNormalize (Value : BOOLEAN);
+BEGIN
+ FXmlParser.Normalize := Value;
+END;
+
+
+PROCEDURE TCustomXmlScanner.WhenXmlProlog(XmlVersion, Encoding: STRING; Standalone : BOOLEAN);
+ // Is called when the parser has parsed the <? xml ?> declaration of the prolog
+BEGIN
+ IF Assigned (FOnXmlProlog) THEN FOnXmlProlog (Self, XmlVersion, Encoding, Standalone);
+END;
+
+
+PROCEDURE TCustomXmlScanner.WhenComment (Comment : STRING);
+ // Is called when the parser has parsed a <!-- comment -->
+BEGIN
+ IF Assigned (FOnComment) THEN FOnComment (Self, Comment);
+END;
+
+
+PROCEDURE TCustomXmlScanner.WhenPI (Target, Content: STRING; Attributes : TAttrList);
+ // Is called when the parser has parsed a <?processing instruction ?>
+BEGIN
+ IF Assigned (FOnPI) THEN FOnPI (Self, Target, Content, Attributes);
+END;
+
+
+PROCEDURE TCustomXmlScanner.WhenDtdRead (RootElementName : STRING);
+ // Is called when the parser has completely parsed the DTD
+BEGIN
+ IF Assigned (FOnDtdRead) THEN FOnDtdRead (Self, RootElementName);
+END;
+
+
+PROCEDURE TCustomXmlScanner.WhenStartTag (TagName : STRING; Attributes : TAttrList);
+ // Is called when the parser has parsed a start tag like <p>
+BEGIN
+ IF Assigned (FOnStartTag) THEN FOnStartTag (Self, TagName, Attributes);
+END;
+
+
+PROCEDURE TCustomXmlScanner.WhenEmptyTag (TagName : STRING; Attributes : TAttrList);
+ // Is called when the parser has parsed an Empty Element Tag like <br/>
+BEGIN
+ IF Assigned (FOnEmptyTag) THEN FOnEmptyTag (Self, TagName, Attributes);
+END;
+
+
+PROCEDURE TCustomXmlScanner.WhenEndTag (TagName : STRING);
+ // Is called when the parser has parsed an End Tag like </p>
+BEGIN
+ IF Assigned (FOnEndTag) THEN FOnEndTag (Self, TagName);
+END;
+
+
+PROCEDURE TCustomXmlScanner.WhenContent (Content : STRING);
+ // Is called when the parser has parsed an element's text content
+BEGIN
+ IF Assigned (FOnContent) THEN FOnContent (Self, Content);
+END;
+
+
+PROCEDURE TCustomXmlScanner.WhenCData (Content : STRING);
+ // Is called when the parser has parsed a CDATA section
+BEGIN
+ IF Assigned (FOnCData) THEN FOnCData (Self, Content);
+END;
+
+
+PROCEDURE TCustomXmlScanner.WhenElement (ElemDef : TElemDef);
+ // Is called when the parser has parsed an <!ELEMENT> definition
+ // inside the DTD
+BEGIN
+ IF Assigned (FOnElement) THEN FOnElement (Self, ElemDef);
+END;
+
+
+PROCEDURE TCustomXmlScanner.WhenAttList (ElemDef : TElemDef);
+ // Is called when the parser has parsed an <!ATTLIST> definition
+ // inside the DTD
+BEGIN
+ IF Assigned (FOnAttList) THEN FOnAttList (Self, ElemDef);
+END;
+
+
+PROCEDURE TCustomXmlScanner.WhenEntity (EntityDef : TEntityDef);
+ // Is called when the parser has parsed an <!ENTITY> definition
+ // inside the DTD
+BEGIN
+ IF Assigned (FOnEntity) THEN FOnEntity (Self, EntityDef);
+END;
+
+
+PROCEDURE TCustomXmlScanner.WhenNotation (NotationDef : TNotationDef);
+ // Is called when the parser has parsed a <!NOTATION> definition
+ // inside the DTD
+BEGIN
+ IF Assigned (FOnNotation) THEN FOnNotation (Self, NotationDef);
+END;
+
+
+PROCEDURE TCustomXmlScanner.WhenDtdError (ErrorPos : PChar);
+ // Is called when the parser has found an Error in the DTD
+BEGIN
+ IF Assigned (FOnDtdError) THEN FOnDtdError (Self, ErrorPos);
+END;
+
+
+PROCEDURE TCustomXmlScanner.Execute;
+ // Perform scanning
+ // Scanning is done synchronously, i.e. you can expect events to be triggered
+ // in the order of the XML data stream. Execute will finish when the whole XML
+ // document has been scanned or when the StopParser property has been set to TRUE.
+BEGIN
+ FStopParser := FALSE;
+ FXmlParser.StartScan;
+ WHILE FXmlParser.Scan AND (NOT FStopParser) DO
+ CASE FXmlParser.CurPartType OF
+ ptNone : ;
+ ptXmlProlog : WhenXmlProlog (FXmlParser.XmlVersion, FXmlParser.Encoding, FXmlParser.Standalone);
+ ptComment : WhenComment (StrSFPas (FXmlParser.CurStart, FXmlParser.CurFinal));
+ ptPI : WhenPI (FXmlParser.CurName, FXmlParser.CurContent, FXmlParser.CurAttr);
+ ptDtdc : WhenDtdRead (FXmlParser.RootName);
+ ptStartTag : WhenStartTag (FXmlParser.CurName, FXmlParser.CurAttr);
+ ptEmptyTag : WhenEmptyTag (FXmlParser.CurName, FXmlParser.CurAttr);
+ ptEndTag : WhenEndTag (FXmlParser.CurName);
+ ptContent : WhenContent (FXmlParser.CurContent);
+ ptCData : WhenCData (FXmlParser.CurContent);
+ END;
+END;
+
+
+END.
diff --git a/packages/sdl/src/logger.pas b/packages/sdl/src/logger.pas
new file mode 100644
index 0000000000..ad9b24e6ab
--- /dev/null
+++ b/packages/sdl/src/logger.pas
@@ -0,0 +1,189 @@
+unit logger;
+{
+ $Id: logger.pas,v 1.2 2006/11/26 16:58:04 savage Exp $
+
+}
+{******************************************************************************}
+{ }
+{ Error Logging Unit }
+{ }
+{ The initial developer of this Pascal code was : }
+{ Dominique Louis <Dominique@SavageSoftware.com.au> }
+{ }
+{ Portions created by Dominique Louis are }
+{ Copyright (C) 2000 - 2001 Dominique Louis. }
+{ }
+{ }
+{ }
+{ Contributor(s) }
+{ -------------- }
+{ }
+{ }
+{ Obtained through: }
+{ Joint Endeavour of Delphi Innovators ( Project JEDI ) }
+{ }
+{ You may retrieve the latest version of this file at the Project }
+{ JEDI home page, located at http://delphi-jedi.org }
+{ }
+{ The contents of this file are used with permission, subject to }
+{ the Mozilla Public License Version 1.1 (the "License"); you may }
+{ not use this file except in compliance with the License. You may }
+{ obtain a copy of the License at }
+{ http://www.mozilla.org/MPL/MPL-1.1.html }
+{ }
+{ Software distributed under the License is distributed on an }
+{ "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or }
+{ implied. See the License for the specific language governing }
+{ rights and limitations under the License. }
+{ }
+{ Description }
+{ ----------- }
+{ Logging functions... }
+{ }
+{ }
+{ Requires }
+{ -------- }
+{ SDL.dll on Windows platforms }
+{ libSDL-1.1.so.0 on Linux platform }
+{ }
+{ Programming Notes }
+{ ----------------- }
+{ }
+{ }
+{ }
+{ }
+{ Revision History }
+{ ---------------- }
+{ 2001 - DL : Initial creation }
+{ 25/10/2001 - DRE : Added $M+ directive to allow published }
+{ in classes. Added a compile directive }
+{ around fmShareExclusive as this does not }
+{ exist in Free Pascal }
+{ }
+{******************************************************************************}
+{
+ $Log: logger.pas,v $
+ Revision 1.2 2006/11/26 16:58:04 savage
+ Modifed to create separate log files. Therefore each instance running from the same directory will have their own individual log file, prepended with a number.
+
+ Revision 1.1 2004/02/05 00:08:20 savage
+ Module 1.0 release
+
+
+}
+
+{$I jedi-sdl.inc}
+
+{$WEAKPACKAGEUNIT OFF}
+
+interface
+
+uses
+ Classes,
+ SysUtils;
+
+type
+ TLogger = class
+ private
+ FFileHandle : TextFile;
+ FApplicationName : string;
+ FApplicationPath : string;
+ protected
+
+ public
+ constructor Create;
+ destructor Destroy; override;
+ function GetApplicationName: string;
+ function GetApplicationPath: string;
+ procedure LogError( ErrorMessage : string; Location : string );
+ procedure LogWarning( WarningMessage : string; Location : string );
+ procedure LogStatus( StatusMessage : string; Location : string );
+ published
+ property ApplicationName : string read GetApplicationName;
+ property ApplicationPath : string read GetApplicationPath;
+ end;
+
+var
+ Log : TLogger;
+
+implementation
+
+{ TLogger }
+constructor TLogger.Create;
+var
+ FileName : string;
+ FileNo : integer;
+begin
+ FApplicationName := ExtractFileName( ParamStr(0) );
+ FApplicationPath := ExtractFilePath( ParamStr(0) );
+ FileName := FApplicationPath + ChangeFileExt( FApplicationName, '.log' );
+ FileNo := 0;
+ while FileExists( FileName ) do
+ begin
+ inc( FileNo );
+ FileName := FApplicationPath + IntToStr( FileNo ) + ChangeFileExt( FApplicationName, '.log' )
+ end;
+ AssignFile( FFileHandle, FileName );
+ ReWrite( FFileHandle );
+ (*inherited Create( FApplicationPath + ChangeFileExt( FApplicationName, '.log' ),
+ fmCreate {$IFNDEF FPC}or fmShareExclusive{$ENDIF} );*)
+end;
+
+destructor TLogger.Destroy;
+begin
+ CloseFile( FFileHandle );
+ inherited;
+end;
+
+function TLogger.GetApplicationName: string;
+begin
+ result := FApplicationName;
+end;
+
+function TLogger.GetApplicationPath: string;
+begin
+ result := FApplicationPath;
+end;
+
+procedure TLogger.LogError(ErrorMessage, Location: string);
+var
+ S : string;
+begin
+ S := '*** ERROR *** : @ ' + TimeToStr(Time) + ' MSG : ' + ErrorMessage + ' IN : ' + Location + #13#10;
+ WriteLn( FFileHandle, S );
+ Flush( FFileHandle );
+end;
+
+procedure TLogger.LogStatus(StatusMessage, Location: string);
+var
+ S : string;
+begin
+ S := 'STATUS INFO : @ ' + TimeToStr(Time) + ' MSG : ' + StatusMessage + ' IN : ' + Location + #13#10;
+ WriteLn( FFileHandle, S );
+ Flush( FFileHandle );
+end;
+
+procedure TLogger.LogWarning(WarningMessage, Location: string);
+var
+ S : string;
+begin
+ S := '=== WARNING === : @ ' + TimeToStr(Time) + ' MSG : ' + WarningMessage + ' IN : ' + Location + #13#10;
+ WriteLn( FFileHandle, S );
+ Flush( FFileHandle );
+end;
+
+initialization
+begin
+ Log := TLogger.Create;
+ Log.LogStatus( 'Starting Application', 'Initialization' );
+end;
+
+finalization
+begin
+ Log.LogStatus( 'Terminating Application', 'Finalization' );
+ Log.Free;
+ Log := nil;
+end;
+
+end.
+ \ No newline at end of file
diff --git a/packages/sdl/src/powersdl.inc b/packages/sdl/src/powersdl.inc
new file mode 100644
index 0000000000..ae17e266d3
--- /dev/null
+++ b/packages/sdl/src/powersdl.inc
@@ -0,0 +1,176 @@
+
+var PowerSDLBase : pLibrary;
+
+const
+ POWERSDLNAME : PChar = 'powersdl.library';
+
+function SDL_Init(flags : DWord) : LongInt; syscall basesysv PowerSDLBase 028;
+procedure SDL_RealQuit; syscall basesysv PowerSDLBase 034;
+function SDL_InitSubSystem(flags : DWord) : LongInt; syscall basesysv PowerSDLBase 040;
+procedure SDL_QuitSubSystem(flags : DWord); syscall basesysv PowerSDLBase 046;
+function SDL_WasInit(flags : DWord) : DWord; syscall basesysv PowerSDLBase 052;
+function SDL_RWFromFile(const file_ : pChar; const mode : pChar) : pSDL_RWops; syscall basesysv PowerSDLBase 058;
+function SDL_RWFromMem(mem : Pointer; size : LongInt) : pSDL_RWops; syscall basesysv PowerSDLBase 070;
+function SDL_AllocRW : pSDL_RWops; syscall basesysv PowerSDLBase 076;
+procedure SDL_FreeRW(area : pSDL_RWops); syscall basesysv PowerSDLBase 082;
+function SDL_LoadBMP_RW(src : pSDL_RWops; freesrc : LongInt) : pSDL_Surface; syscall basesysv PowerSDLBase 088;
+function SDL_DisplayFormat(surface : pSDL_Surface) : pSDL_Surface; syscall basesysv PowerSDLBase 094;
+procedure SDL_FreeSurface(surface : pSDL_Surface); syscall basesysv PowerSDLBase 100;
+function SDL_FillRect(dst : pSDL_Surface; dstrect : pSDL_Rect; color : DWord) : LongInt; syscall basesysv PowerSDLBase 106;
+function SDL_UpperBlit(src : pSDL_Surface; srcrect : pSDL_Rect; dst : pSDL_Surface; dstrect : pSDL_Rect) : LongInt; syscall basesysv PowerSDLBase 112;
+function SDL_Flip(screen : pSDL_Surface) : LongInt; syscall basesysv PowerSDLBase 118;
+procedure SDL_UpdateRects(screen : pSDL_Surface; numrects : LongInt; rects : pSDL_Rect); syscall basesysv PowerSDLBase 124;
+procedure SDL_UpdateRect(screen : pSDL_Surface; x : LongInt; y : LongInt; w : DWord; h : DWord); syscall basesysv PowerSDLBase 130;
+function SDL_SetVideoMode(width : LongInt; height : LongInt; bpp : LongInt; flags : DWord) : pSDL_Surface; syscall basesysv PowerSDLBase 142;
+function SDL_MapRGB(format : pSDL_PixelFormat; r : Byte; g : Byte; b : Byte) : DWord; syscall basesysv PowerSDLBase 148;
+function SDL_MapRGBA(format : pSDL_PixelFormat; r : Byte; g : Byte; b : Byte; a : Byte) : DWord; syscall basesysv PowerSDLBase 154;
+function SDL_VideoDriverName(namebuf : pChar; maxlen : LongInt) : pChar; syscall basesysv PowerSDLBase 160;
+function SDL_GetVideoSurface : pSDL_Surface; syscall basesysv PowerSDLBase 166;
+function SDL_VideoModeOK(width : LongInt; height : LongInt; bpp : LongInt; flags : DWord) : LongInt; syscall basesysv PowerSDLBase 172;
+function SDL_ListModes(format : pSDL_PixelFormat; flags : DWord) : ppSDL_Rect; syscall basesysv PowerSDLBase 178;
+function SDL_SetGamma(red : LongInt; green : LongInt; blue : LongInt) : LongInt; syscall basesysv PowerSDLBase 184;
+function SDL_SetGammaRamp(const red : LongInt; const green : LongInt; const blue : LongInt) : LongInt; syscall basesysv PowerSDLBase 190;
+function SDL_GetGammaRamp(var red : Word; var green : Word; var blue : Word) : LongInt; syscall basesysv PowerSDLBase 196;
+function SDL_SetColors(surface : pSDL_Surface; colors : pSDL_Color; firstcolor : LongInt; ncolors : LongInt) : LongInt; syscall basesysv PowerSDLBase 202;
+function SDL_SetPalette(surface : pSDL_Surface; flags : LongInt; colors : pSDL_Color; firstcolor : LongInt; ncolors : LongInt) : LongInt; syscall basesysv PowerSDLBase 208;
+procedure SDL_GetRGB(pixel : DWord; format : pSDL_PixelFormat; r : pChar; g : pChar; b : pChar); syscall basesysv PowerSDLBase 214;
+procedure SDL_GetRGBA(pixel : DWord; format : pSDL_PixelFormat; r : pChar; g : pChar; b : pChar; a : pChar); syscall basesysv PowerSDLBase 220;
+function SDL_CreateRGBSurface(flags : DWord; width : LongInt; height : LongInt; depth : LongInt; Rmask : DWord; Gmask : DWord; Bmask : DWord; Amask : DWord) : pSDL_Surface; syscall basesysv PowerSDLBase 226;
+function SDL_CreateRGBSurfaceFrom(pixels : Pointer; width : LongInt; height : LongInt; depth : LongInt; pitch : LongInt; Rmask : DWord; Gmask : DWord; Bmask : DWord; Amask : DWord) : pSDL_Surface; syscall basesysv PowerSDLBase 232;
+function SDL_LockSurface(surface : pSDL_Surface) : LongInt; syscall basesysv PowerSDLBase 238;
+procedure SDL_UnlockSurface(surface : pSDL_Surface); syscall basesysv PowerSDLBase 244;
+function SDL_SaveBMP_RW(surface : pSDL_Surface; dst : pSDL_RWops; freedst : LongInt) : LongInt; syscall basesysv PowerSDLBase 250;
+function SDL_SetColorKey(surface : pSDL_Surface; flag : DWord; key : DWord) : LongInt; syscall basesysv PowerSDLBase 256;
+function SDL_SetAlpha(surface : pSDL_Surface; flag : DWord; alpha : Byte) : LongInt; syscall basesysv PowerSDLBase 262;
+function SDL_SetClipRect(surface : pSDL_Surface; const rect : LongInt) : LongInt; syscall basesysv PowerSDLBase 268;
+procedure SDL_GetClipRect(surface : pSDL_Surface; rect : pSDL_Rect); syscall basesysv PowerSDLBase 274;
+function SDL_ConvertSurface(src : pSDL_Surface; fmt : pSDL_PixelFormat; flags : DWord) : pSDL_Surface; syscall basesysv PowerSDLBase 280;
+function SDL_DisplayFormatAlpha(surface : pSDL_Surface) : pSDL_Surface; syscall basesysv PowerSDLBase 286;
+function SDL_CreateYUVOverlay(width : LongInt; height : LongInt; format : DWord; display : pSDL_Surface) : pSDL_Overlay; syscall basesysv PowerSDLBase 292;
+function SDL_LockYUVOverlay(overlay : pSDL_Overlay) : LongInt; syscall basesysv PowerSDLBase 298;
+procedure SDL_UnlockYUVOverlay(overlay : pSDL_Overlay); syscall basesysv PowerSDLBase 304;
+function SDL_DisplayYUVOverlay(overlay : pSDL_Overlay; dstrect : pSDL_Rect) : LongInt; syscall basesysv PowerSDLBase 310;
+procedure SDL_FreeYUVOverlay(overlay : pSDL_Overlay); syscall basesysv PowerSDLBase 316;
+function SDL_GL_LoadLibrary(const path : pChar) : LongInt; syscall basesysv PowerSDLBase 322;
+function SDL_GL_GetProcAddress(const proc : pChar) : Pointer; syscall basesysv PowerSDLBase 328;
+function SDL_GL_SetAttribute(attr : LongInt; value : LongInt) : LongInt; syscall basesysv PowerSDLBase 334;
+function SDL_GL_GetAttribute(attr : LongInt; value : pLongInt) : LongInt; syscall basesysv PowerSDLBase 340;
+procedure SDL_GL_SwapBuffers; syscall basesysv PowerSDLBase 346;
+procedure SDL_GL_UpdateRects(numrects : LongInt; rects : pSDL_Rect); syscall basesysv PowerSDLBase 352;
+procedure SDL_GL_Lock; syscall basesysv PowerSDLBase 358;
+procedure SDL_GL_Unlock; syscall basesysv PowerSDLBase 364;
+procedure SDL_WM_SetCaption(const title : pChar; const icon : pChar); syscall basesysv PowerSDLBase 370;
+procedure SDL_WM_GetCaption(var title : pShortInt; var icon : pShortInt); syscall basesysv PowerSDLBase 376;
+procedure SDL_WM_SetIcon(icon : pSDL_Surface; mask : pChar); syscall basesysv PowerSDLBase 382;
+function SDL_WM_IconifyWindow : LongInt; syscall basesysv PowerSDLBase 388;
+function SDL_WM_ToggleFullScreen(surface : pSDL_Surface) : LongInt; syscall basesysv PowerSDLBase 394;
+function SDL_WM_GrabInput(mode : LongInt) : LongInt; syscall basesysv PowerSDLBase 400;
+function SDL_GetTicks : DWord; syscall basesysv PowerSDLBase 406;
+procedure SDL_Delay(ms : DWord); syscall basesysv PowerSDLBase 412;
+function SDL_SetTimer(interval : DWord; callback : TProcedure) : LongInt; syscall basesysv PowerSDLBase 418;
+function SDL_AddTimer(interval : DWord; callback : TProcedure; param : Pointer) : tSDL_TimerID; syscall basesysv PowerSDLBase 424;
+function SDL_RemoveTimer(t : tSDL_TimerID) : LongInt; syscall basesysv PowerSDLBase 430;
+procedure SDL_PumpEvents; syscall basesysv PowerSDLBase 436;
+function SDL_PollEvent(event : pLongInt) : LongInt; syscall basesysv PowerSDLBase 442;
+function SDL_WaitEvent(event : pLongInt) : LongInt; syscall basesysv PowerSDLBase 448;
+function SDL_PeepEvents(events : pLongInt; numevents : LongInt; action : LongInt; mask : DWord) : LongInt; syscall basesysv PowerSDLBase 454;
+function SDL_PushEvent(event : pLongInt) : LongInt; syscall basesysv PowerSDLBase 460;
+procedure SDL_SetEventFilter(filter : Pointer); syscall basesysv PowerSDLBase 466;
+function SDL_GetEventFilter : Pointer; syscall basesysv PowerSDLBase 472;
+function SDL_EventState(type_ : Byte; state : LongInt) : Byte; syscall basesysv PowerSDLBase 478;
+function SDL_NumJoysticks : LongInt; syscall basesysv PowerSDLBase 484;
+function SDL_JoystickName(device_index : LongInt) : pChar; syscall basesysv PowerSDLBase 490;
+function SDL_JoystickOpen(device_index : LongInt) : pSDL_Joystick; syscall basesysv PowerSDLBase 496;
+function SDL_JoystickOpened(device_index : LongInt) : LongInt; syscall basesysv PowerSDLBase 502;
+function SDL_JoystickIndex(joystick : pSDL_Joystick) : LongInt; syscall basesysv PowerSDLBase 508;
+function SDL_JoystickNumAxes(joystick : pSDL_Joystick) : LongInt; syscall basesysv PowerSDLBase 514;
+function SDL_JoystickNumBalls(joystick : pSDL_Joystick) : LongInt; syscall basesysv PowerSDLBase 520;
+function SDL_JoystickNumHats(joystick : pSDL_Joystick) : LongInt; syscall basesysv PowerSDLBase 526;
+function SDL_JoystickNumButtons(joystick : pSDL_Joystick) : LongInt; syscall basesysv PowerSDLBase 532;
+procedure SDL_JoystickUpdate; syscall basesysv PowerSDLBase 538;
+function SDL_JoystickEventState(state : LongInt) : LongInt; syscall basesysv PowerSDLBase 544;
+function SDL_JoystickGetAxis(joystick : pSDL_Joystick; axis : LongInt) : Integer; syscall basesysv PowerSDLBase 550;
+function SDL_JoystickGetHat(joystick : pSDL_Joystick; hat : LongInt) : Byte; syscall basesysv PowerSDLBase 556;
+function SDL_JoystickGetBall(joystick : pSDL_Joystick; ball : LongInt; dx : pLongInt; dy : pLongInt) : LongInt; syscall basesysv PowerSDLBase 562;
+function SDL_JoystickGetButton(joystick : pSDL_Joystick; button : LongInt) : Byte; syscall basesysv PowerSDLBase 568;
+procedure SDL_JoystickClose(joystick : pSDL_Joystick); syscall basesysv PowerSDLBase 574;
+function SDL_EnableUNICODE(enable : LongInt) : LongInt; syscall basesysv PowerSDLBase 580;
+function SDL_EnableKeyRepeat(delay : LongInt; interval : LongInt) : LongInt; syscall basesysv PowerSDLBase 586;
+function SDL_GetKeyState(numkeys : pLongInt) : pChar; syscall basesysv PowerSDLBase 592;
+function SDL_GetModState : LongInt; syscall basesysv PowerSDLBase 598;
+procedure SDL_SetModState(modstate : LongInt); syscall basesysv PowerSDLBase 604;
+function SDL_GetKeyName(key : LongInt) : pChar; syscall basesysv PowerSDLBase 610;
+function SDL_GetMouseState(x : pLongInt; y : pLongInt) : Byte; syscall basesysv PowerSDLBase 616;
+function SDL_GetRelativeMouseState(x : pLongInt; y : pLongInt) : Byte; syscall basesysv PowerSDLBase 622;
+procedure SDL_WarpMouse(x : Word; y : Word); syscall basesysv PowerSDLBase 628;
+function SDL_CreateCursor(data : pChar; mask : pChar; w : LongInt; h : LongInt; hot_x : LongInt; hot_y : LongInt) : pSDL_Cursor; syscall basesysv PowerSDLBase 634;
+procedure SDL_SetCursor(cursor : pSDL_Cursor); syscall basesysv PowerSDLBase 640;
+function SDL_GetCursor : pSDL_Cursor; syscall basesysv PowerSDLBase 646;
+procedure SDL_FreeCursor(cursor : pSDL_Cursor); syscall basesysv PowerSDLBase 652;
+function SDL_ShowCursor(toggle : LongInt) : LongInt; syscall basesysv PowerSDLBase 658;
+function SDL_GetAppState : Byte; syscall basesysv PowerSDLBase 664;
+function SDL_GetError : pChar; syscall basesysv PowerSDLBase 676;
+procedure SDL_ClearError; syscall basesysv PowerSDLBase 682;
+function SDL_AudioInit(const driver_name : pChar) : LongInt; syscall basesysv PowerSDLBase 688;
+procedure SDL_AudioQuit; syscall basesysv PowerSDLBase 694;
+function SDL_AudioDriverName(namebuf : pChar; maxlen : LongInt) : pChar; syscall basesysv PowerSDLBase 700;
+function SDL_OpenAudio(desired : pSDL_AudioSpec; obtained : pSDL_AudioSpec) : LongInt; syscall basesysv PowerSDLBase 706;
+function SDL_GetAudioStatus : LongInt; syscall basesysv PowerSDLBase 712;
+procedure SDL_PauseAudio(pause_on : LongInt); syscall basesysv PowerSDLBase 718;
+function SDL_LoadWAV_RW(src : pSDL_RWops; freesrc : LongInt; spec : pSDL_AudioSpec; audio_buf : pByte; audio_len : PDWord) : pSDL_AudioSpec; syscall basesysv PowerSDLBase 724;
+procedure SDL_FreeWAV(audio_buf : pChar); syscall basesysv PowerSDLBase 730;
+function SDL_BuildAudioCVT(cvt : pSDL_AudioCVT; src_format : Word; src_channels : Byte; src_rate : LongInt; dst_format : Word; dst_channels : Byte; dst_rate : LongInt) : LongInt; syscall basesysv PowerSDLBase 736;
+function SDL_ConvertAudio(cvt : pSDL_AudioCVT) : LongInt; syscall basesysv PowerSDLBase 742;
+procedure SDL_MixAudio(dst : pChar; const src : LongInt; len : DWord; volume : LongInt); syscall basesysv PowerSDLBase 748;
+procedure SDL_LockAudio; syscall basesysv PowerSDLBase 754;
+procedure SDL_UnlockAudio; syscall basesysv PowerSDLBase 760;
+procedure SDL_CloseAudio; syscall basesysv PowerSDLBase 766;
+function SDL_CreateThread(fn : TProcedure; data : Pointer) : pSDL_Thread; syscall basesysv PowerSDLBase 772;
+function SDL_ThreadID : DWord; syscall basesysv PowerSDLBase 778;
+function SDL_GetThreadID(thread : pSDL_Thread) : DWord; syscall basesysv PowerSDLBase 784;
+procedure SDL_WaitThread(thread : pSDL_Thread; status : pLongInt); syscall basesysv PowerSDLBase 790;
+procedure SDL_KillThread(thread : pSDL_Thread); syscall basesysv PowerSDLBase 796;
+function SDL_SoftStretch(src : pSDL_Surface; srcrect : pSDL_Rect; dest : pSDL_Surface; dstrect : pSDL_Rect) : LongInt; syscall basesysv PowerSDLBase 808;
+function SDL_UNIX2AMIGA(const file_ : pChar) : pChar; syscall basesysv PowerSDLBase 814;
+function SDL_AMIGA_RWFromFile(const file_ : pChar; const mode : pChar) : pSDL_RWops; syscall basesysv PowerSDLBase 820;
+function SDL_AMIGA_RWFromFP(fp : LongInt; autoclose : LongInt) : pSDL_RWops; syscall basesysv PowerSDLBase 826;
+function SDL_CDNumDrives : LongInt; syscall basesysv PowerSDLBase 832;
+function SDL_CDName(drive : LongInt) : pChar; syscall basesysv PowerSDLBase 838;
+function SDL_CDOpen(drive : LongInt) : pSDL_CD; syscall basesysv PowerSDLBase 844;
+function SDL_CDStatus(cdrom : pSDL_CD) : LongInt; syscall basesysv PowerSDLBase 850;
+function SDL_CDPlay(cdrom : pSDL_CD; sframe : LongInt; length : LongInt) : LongInt; syscall basesysv PowerSDLBase 856;
+function SDL_CDPause(cdrom : pSDL_CD) : LongInt; syscall basesysv PowerSDLBase 862;
+function SDL_CDResume(cdrom : pSDL_CD) : LongInt; syscall basesysv PowerSDLBase 868;
+function SDL_CDStop(cdrom : pSDL_CD) : LongInt; syscall basesysv PowerSDLBase 874;
+function SDL_CDEject(cdrom : pSDL_CD) : LongInt; syscall basesysv PowerSDLBase 880;
+procedure SDL_CDClose(cdrom : pSDL_CD); syscall basesysv PowerSDLBase 886;
+function SDL_CreateMutex : pSDL_mutex; syscall basesysv PowerSDLBase 892;
+procedure SDL_DestroyMutex(mutex : pSDL_mutex); syscall basesysv PowerSDLBase 898;
+function SDL_mutexP(mutex : pSDL_mutex) : LongInt; syscall basesysv PowerSDLBase 904;
+function SDL_mutexV(mutex : pSDL_mutex) : LongInt; syscall basesysv PowerSDLBase 910;
+function SDL_CreateSemaphore(initial_value : DWord) : pSDL_semaphore; syscall basesysv PowerSDLBase 916;
+procedure SDL_DestroySemaphore(sem : pSDL_semaphore); syscall basesysv PowerSDLBase 922;
+function SDL_SemTryWait(sem : pSDL_semaphore) : LongInt; syscall basesysv PowerSDLBase 928;
+function SDL_SemWaitTimeout(sem : pSDL_semaphore; timeout : DWord) : LongInt; syscall basesysv PowerSDLBase 934;
+function SDL_SemWait(sem : pSDL_semaphore) : LongInt; syscall basesysv PowerSDLBase 940;
+function SDL_SemValue(sem : pSDL_semaphore) : DWord; syscall basesysv PowerSDLBase 946;
+function SDL_SemPost(sem : pSDL_semaphore) : LongInt; syscall basesysv PowerSDLBase 952;
+procedure SDL_Error(code : TSDL_errorcode); syscall basesysv PowerSDLBase 958;
+function SDL_CreateCond : pSDL_cond; syscall basesysv PowerSDLBase 964;
+procedure SDL_DestroyCond(cond : pSDL_cond); syscall basesysv PowerSDLBase 970;
+function SDL_CondSignal(cond : pSDL_cond) : LongInt; syscall basesysv PowerSDLBase 976;
+function SDL_CondBroadcast(cond : pSDL_cond) : LongInt; syscall basesysv PowerSDLBase 982;
+function SDL_CondWaitTimeout(cond : pSDL_cond; mutex : pSDL_mutex; ms : DWord) : LongInt; syscall basesysv PowerSDLBase 988;
+function SDL_CondWait(cond : pSDL_cond; mutex : pSDL_mutex) : LongInt; syscall basesysv PowerSDLBase 994;
+procedure SDL_InitTGL(var glc : Pointer; var tgl : Pointer); syscall basesysv PowerSDLBase 1000;
+function SDL_HasAltiVec : LongInt; syscall basesysv PowerSDLBase 1096;
+function SDL_HasRDTSC : LongInt; syscall basesysv PowerSDLBase 1102;
+function SDL_HasMMX : LongInt; syscall basesysv PowerSDLBase 1108;
+function SDL_Has3DNow : LongInt; syscall basesysv PowerSDLBase 1114;
+function SDL_HasSSE : LongInt; syscall basesysv PowerSDLBase 1120;
+function SDL_HasMMXExt : LongInt; syscall basesysv PowerSDLBase 1126;
+function SDL_Has3DNowExt : LongInt; syscall basesysv PowerSDLBase 1132;
+function SDL_HasSSE2 : LongInt; syscall basesysv PowerSDLBase 1138;
+function SDL_LowerBlit(src : pSDL_Surface; srcrect : pSDL_Rect; dst : pSDL_Surface; dstrect : pSDL_Rect) : LongInt; syscall basesysv PowerSDLBase 1144;
+function SDL_CDPlayTracks(cdrom : pSDL_CD; strack : LongInt; sframe : LongInt; ntracks : LongInt; nframes : LongInt) : LongInt; syscall basesysv PowerSDLBase 1150;
+procedure SDL_OpenPrefs; syscall basesysv PowerSDLBase 1156;
diff --git a/packages/sdl/src/sdl.pas b/packages/sdl/src/sdl.pas
new file mode 100644
index 0000000000..b5416d30b3
--- /dev/null
+++ b/packages/sdl/src/sdl.pas
@@ -0,0 +1,4288 @@
+unit sdl;
+{
+ $Id: sdl.pas,v 1.31 2007/05/29 21:30:48 savage Exp $
+
+}
+{******************************************************************************}
+{ }
+{ JEDI-SDL : Pascal units for SDL - Simple DirectMedia Layer }
+{ Conversion of the Simple DirectMedia Layer Headers }
+{ }
+{ Portions created by Sam Lantinga <slouken@devolution.com> are }
+{ Copyright (C) 1997-2004 Sam Lantinga }
+{ 5635-34 Springhouse Dr. }
+{ Pleasanton, CA 94588 (USA) }
+{ }
+{ All Rights Reserved. }
+{ }
+{ The original files are : SDL.h }
+{ SDL_main.h }
+{ SDL_types.h }
+{ SDL_rwops.h }
+{ SDL_timer.h }
+{ SDL_audio.h }
+{ SDL_cdrom.h }
+{ SDL_joystick.h }
+{ SDL_mouse.h }
+{ SDL_keyboard.h }
+{ SDL_events.h }
+{ SDL_video.h }
+{ SDL_byteorder.h }
+{ SDL_version.h }
+{ SDL_active.h }
+{ SDL_thread.h }
+{ SDL_mutex .h }
+{ SDL_getenv.h }
+{ SDL_loadso.h }
+{ }
+{ The initial developer of this Pascal code was : }
+{ Dominique Louis <Dominique@SavageSoftware.com.au> }
+{ }
+{ Portions created by Dominique Louis are }
+{ Copyright (C) 2000 - 2004 Dominique Louis. }
+{ }
+{ }
+{ Contributor(s) }
+{ -------------- }
+{ Tom Jones <tigertomjones@gmx.de> His Project inspired this conversion }
+{ Matthias Thoma <ma.thoma@gmx.de> }
+{ }
+{ Obtained through: }
+{ Joint Endeavour of Delphi Innovators ( Project JEDI ) }
+{ }
+{ You may retrieve the latest version of this file at the Project }
+{ JEDI home page, located at http://delphi-jedi.org }
+{ }
+{ The contents of this file are used with permission, subject to }
+{ the Mozilla Public License Version 1.1 (the "License"); you may }
+{ not use this file except in compliance with the License. You may }
+{ obtain a copy of the License at }
+{ http://www.mozilla.org/MPL/MPL-1.1.html }
+{ }
+{ Software distributed under the License is distributed on an }
+{ "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or }
+{ implied. See the License for the specific language governing }
+{ rights and limitations under the License. }
+{ }
+{ Description }
+{ ----------- }
+{ }
+{ }
+{ }
+{ }
+{ }
+{ }
+{ }
+{ Requires }
+{ -------- }
+{ The SDL Runtime libraris on Win32 : SDL.dll on Linux : libSDL.so }
+{ They are available from... }
+{ http://www.libsdl.org . }
+{ }
+{ Programming Notes }
+{ ----------------- }
+{ }
+{ }
+{ }
+{ }
+{ Revision History }
+{ ---------------- }
+{ May 08 2001 - DL : Added Keyboard State Array ( See demos for how to }
+{ use ) }
+{ PKeyStateArr = ^TKeyStateArr; }
+{ TKeyStateArr = array[0..65000] of UInt8; }
+{ As most games will need it. }
+{ }
+{ April 02 2001 - DL : Added SDL_getenv.h definitions and tested version }
+{ 1.2.0 compatability. }
+{ }
+{ March 13 2001 - MT : Added Linux compatibility. }
+{ }
+{ March 10 2001 - MT : Added externalsyms for DEFINES }
+{ Changed the license header }
+{ }
+{ March 09 2001 - MT : Added Kylix Ifdefs/Deleted the uses mmsystem }
+{ }
+{ March 01 2001 - DL : Update conversion of version 1.1.8 }
+{ }
+{ July 22 2001 - DL : Added TUInt8Array and PUIntArray after suggestions }
+{ from Matthias Thoma and Eric Grange. }
+{ }
+{ October 12 2001 - DL : Various changes as suggested by Matthias Thoma and }
+{ David Acklam }
+{ }
+{ October 24 2001 - DL : Added FreePascal support as per suggestions from }
+{ Dean Ellis. }
+{ }
+{ October 27 2001 - DL : Added SDL_BUTTON macro }
+{ }
+{ November 08 2001 - DL : Bug fix as pointed out by Puthoon. }
+{ }
+{ November 29 2001 - DL : Bug fix of SDL_SetGammaRamp as pointed out by Simon}
+{ Rushton. }
+{ }
+{ November 30 2001 - DL : SDL_NOFRAME added as pointed out by Simon Rushton. }
+{ }
+{ December 11 2001 - DL : Added $WEAKPACKAGEUNIT ON to facilitate useage in }
+{ Components }
+{ }
+{ January 05 2002 - DL : Added SDL_Swap32 function as suggested by Matthias }
+{ Thoma and also made sure the _getenv from }
+{ MSVCRT.DLL uses the right calling convention }
+{ }
+{ January 25 2002 - DL : Updated conversion of SDL_AddTimer & }
+{ SDL_RemoveTimer as per suggestions from Matthias }
+{ Thoma. }
+{ }
+{ January 27 2002 - DL : Commented out exported function putenv and getenv }
+{ So that developers get used to using SDL_putenv }
+{ SDL_getenv, as they are more portable }
+{ }
+{ March 05 2002 - DL : Added FreeAnNil procedure for Delphi 4 users. }
+{ }
+{ October 23 2002 - DL : Added Delphi 3 Define of Win32. }
+{ If you intend to you Delphi 3... }
+{ ( which is officially unsupported ) make sure you }
+{ remove references to $EXTERNALSYM in this and other}
+{ SDL files. }
+{ }
+{ November 29 2002 - DL : Fixed bug in Declaration of SDL_GetRGBA that was }
+{ pointed out by Todd Lang }
+{ }
+{ April 03 2003 - DL : Added jedi-sdl.inc include file to support more }
+{ Pascal compilers. Initial support is now included }
+{ for GnuPascal, VirtualPascal, TMT and obviously }
+{ continue support for Delphi Kylix and FreePascal. }
+{ }
+{ April 08 2003 - MK : Aka Mr Kroket - Added Better FPC support }
+{ }
+{ April 24 2003 - DL : under instruction from Alexey Barkovoy, I have added}
+{ better TMT Pascal support and under instruction }
+{ from Prof. Abimbola Olowofoyeku (The African Chief),}
+{ I have added better Gnu Pascal support }
+{ }
+{ April 30 2003 - DL : under instruction from David Mears AKA }
+{ Jason Siletto, I have added FPC Linux support. }
+{ This was compiled with fpc 1.1, so remember to set }
+{ include file path. ie. -Fi/usr/share/fpcsrc/rtl/* }
+{ }
+{
+ $Log: sdl.pas,v $
+ Revision 1.31 2007/05/29 21:30:48 savage
+ Changes as suggested by Almindor for 64bit compatibility.
+
+ Revision 1.30 2007/05/29 19:31:03 savage
+ Fix to TSDL_Overlay structure - thanks David Pethes (aka imcold)
+
+ Revision 1.29 2007/05/20 20:29:11 savage
+ Initial Changes to Handle 64 Bits
+
+ Revision 1.26 2007/02/11 13:38:04 savage
+ Added Nintendo DS support - Thanks Dean.
+
+ Revision 1.25 2006/12/02 00:12:52 savage
+ Updated to latest version
+
+ Revision 1.24 2006/05/18 21:10:04 savage
+ Added 1.2.10 Changes
+
+ Revision 1.23 2005/12/04 23:17:52 drellis
+ Added declaration of SInt8 and PSInt8
+
+ Revision 1.22 2005/05/24 21:59:03 savage
+ Re-arranged uses clause to work on Win32 and Linux, Thanks again Michalis.
+
+ Revision 1.21 2005/05/22 18:42:31 savage
+ Changes as suggested by Michalis Kamburelis. Thanks again.
+
+ Revision 1.20 2005/04/10 11:48:33 savage
+ Changes as suggested by Michalis, thanks.
+
+ Revision 1.19 2005/01/05 01:47:06 savage
+ Changed LibName to reflect what MacOS X should have. ie libSDL*-1.2.0.dylib respectively.
+
+ Revision 1.18 2005/01/04 23:14:41 savage
+ Changed LibName to reflect what most Linux distros will have. ie libSDL*-1.2.so.0 respectively.
+
+ Revision 1.17 2005/01/03 18:40:59 savage
+ Updated Version number to reflect latest one
+
+ Revision 1.16 2005/01/01 02:02:06 savage
+ Updated to v1.2.8
+
+ Revision 1.15 2004/12/24 18:57:11 savage
+ forgot to apply Michalis Kamburelis' patch to the implementation section. now fixed
+
+ Revision 1.14 2004/12/23 23:42:18 savage
+ Applied Patches supplied by Michalis Kamburelis ( THANKS! ), for greater FreePascal compatability.
+
+ Revision 1.13 2004/09/30 22:31:59 savage
+ Updated with slightly different header comments
+
+ Revision 1.12 2004/09/12 21:52:58 savage
+ Slight changes to fix some issues with the sdl classes.
+
+ Revision 1.11 2004/08/14 22:54:30 savage
+ Updated so that Library name defines are correctly defined for MacOS X.
+
+ Revision 1.10 2004/07/20 23:57:33 savage
+ Thanks to Paul Toth for spotting an error in the SDL Audio Convertion structures.
+ In TSDL_AudioCVT the filters variable should point to and array of pointers and not what I had there previously.
+
+ Revision 1.9 2004/07/03 22:07:22 savage
+ Added Bitwise Manipulation Functions for TSDL_VideoInfo struct.
+
+ Revision 1.8 2004/05/10 14:10:03 savage
+ Initial MacOS X support. Fixed defines for MACOS ( Classic ) and DARWIN ( MacOS X ).
+
+ Revision 1.7 2004/04/13 09:32:08 savage
+ Changed Shared object names back to just the .so extension to avoid conflicts on various Linux/Unix distros. Therefore developers will need to create Symbolic links to the actual Share Objects if necessary.
+
+ Revision 1.6 2004/04/01 20:53:23 savage
+ Changed Linux Shared Object names so they reflect the Symbolic Links that are created when installing the RPMs from the SDL site.
+
+ Revision 1.5 2004/02/22 15:32:10 savage
+ SDL_GetEnv Fix so it also works on FPC/Linux. Thanks to Rodrigo for pointing this out.
+
+ Revision 1.4 2004/02/21 23:24:29 savage
+ SDL_GetEnv Fix so that it is not define twice for FPC. Thanks to Rene Hugentobler for pointing out this bug,
+
+ Revision 1.3 2004/02/18 22:35:51 savage
+ Brought sdl.pas up to 1.2.7 compatability
+ Thus...
+ Added SDL_GL_STEREO,
+ SDL_GL_MULTISAMPLEBUFFERS,
+ SDL_GL_MULTISAMPLESAMPLES
+
+ Add DLL/Shared object functions
+ function SDL_LoadObject( const sofile : PChar ) : Pointer;
+
+ function SDL_LoadFunction( handle : Pointer; const name : PChar ) : Pointer;
+
+ procedure SDL_UnloadObject( handle : Pointer );
+
+ Added function to create RWops from const memory: SDL_RWFromConstMem()
+ function SDL_RWFromConstMem(const mem: Pointer; size: Integer) : PSDL_RWops;
+
+ Ported SDL_cpuinfo.h so Now you can test for Specific CPU types.
+
+ Revision 1.2 2004/02/17 21:37:12 savage
+ Tidying up of units
+
+ Revision 1.1 2004/02/05 00:08:20 savage
+ Module 1.0 release
+
+}
+{******************************************************************************}
+
+{$I jedi-sdl.inc}
+
+interface
+
+uses
+{$IFDEF __GPC__}
+ system,
+ {$IFDEF WINDOWS}
+ wintypes,
+ {$ELSE}
+ {$ENDIF}
+ gpc;
+{$ENDIF}
+
+{$IFDEF HAS_TYPES}
+ Types{$IFNDEF NDS},{$ELSE};{$ENDIF}
+{$ENDIF}
+
+{$IFDEF WINDOWS}
+ Windows;
+{$ENDIF}
+
+{$IFDEF UNIX}
+ {$IFDEF FPC}
+ pthreads,
+ baseunix,
+ {$IFNDEF GP2X}
+ unix,
+ {$ELSE}
+ unix;
+ {$ENDIF}
+ {$IFNDEF GP2X}
+ x,
+ xlib;
+ {$ENDIF}
+ {$ELSE}
+ Libc,
+ Xlib;
+ {$ENDIF}
+{$ENDIF}
+
+{$IFDEF __MACH__}
+ GPCMacOSAll;
+{$ENDIF}
+
+{$IFDEF MORPHOS}
+ exec;
+{$ENDIF}
+
+const
+{$IFDEF WINDOWS}
+ SDLLibName = 'SDL.dll';
+{$ENDIF}
+
+{$IFDEF UNIX}
+{$IFDEF DARWIN}
+ SDLLibName = 'libSDL-1.2.0.dylib';
+ {$linklib libSDL-1.2.0}
+{$ELSE}
+ {$IFDEF FPC}
+ SDLLibName = 'libSDL.so';
+ {$ELSE}
+ SDLLibName = 'libSDL-1.2.so.0';
+ {$ENDIF}
+{$ENDIF}
+{$ENDIF}
+
+{$IFDEF MACOS}
+ SDLLibName = 'SDL';
+{$ENDIF}
+
+{$IFDEF NDS}
+ SDLLibName = 'libSDL.a';
+ {$linklib libSDL.a}
+ {$linklib libnds9.a}
+ {$linklib libc.a}
+ {$linklib libgcc.a}
+ {$linklib libsysbase.a}
+{$ENDIF}
+
+{$IFDEF MORPHOS}
+ SDLLibName = 'powersdl.library';
+{$ENDIF}
+
+ // SDL_verion.h constants
+ // Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL
+ SDL_MAJOR_VERSION = 1;
+{$EXTERNALSYM SDL_MAJOR_VERSION}
+ SDL_MINOR_VERSION = 2;
+{$EXTERNALSYM SDL_MINOR_VERSION}
+ SDL_PATCHLEVEL = 11;
+{$EXTERNALSYM SDL_PATCHLEVEL}
+
+ // SDL.h constants
+ SDL_INIT_TIMER = $00000001;
+{$EXTERNALSYM SDL_INIT_TIMER}
+ SDL_INIT_AUDIO = $00000010;
+{$EXTERNALSYM SDL_INIT_AUDIO}
+ SDL_INIT_VIDEO = $00000020;
+{$EXTERNALSYM SDL_INIT_VIDEO}
+ SDL_INIT_CDROM = $00000100;
+{$EXTERNALSYM SDL_INIT_CDROM}
+ SDL_INIT_JOYSTICK = $00000200;
+{$EXTERNALSYM SDL_INIT_JOYSTICK}
+ SDL_INIT_NOPARACHUTE = $00100000; // Don't catch fatal signals
+{$EXTERNALSYM SDL_INIT_NOPARACHUTE}
+ SDL_INIT_EVENTTHREAD = $01000000; // Not supported on all OS's
+{$EXTERNALSYM SDL_INIT_EVENTTHREAD}
+ SDL_INIT_EVERYTHING = $0000FFFF;
+{$EXTERNALSYM SDL_INIT_EVERYTHING}
+
+ // SDL_error.h constants
+ ERR_MAX_STRLEN = 128;
+{$EXTERNALSYM ERR_MAX_STRLEN}
+ ERR_MAX_ARGS = 5;
+{$EXTERNALSYM ERR_MAX_ARGS}
+
+ // SDL_types.h constants
+ SDL_PRESSED = $01;
+{$EXTERNALSYM SDL_PRESSED}
+ SDL_RELEASED = $00;
+{$EXTERNALSYM SDL_RELEASED}
+
+ // SDL_timer.h constants
+ // This is the OS scheduler timeslice, in milliseconds
+ SDL_TIMESLICE = 10;
+{$EXTERNALSYM SDL_TIMESLICE}
+ // This is the maximum resolution of the SDL timer on all platforms
+ TIMER_RESOLUTION = 10; // Experimentally determined
+{$EXTERNALSYM TIMER_RESOLUTION}
+
+ // SDL_audio.h constants
+ AUDIO_U8 = $0008; // Unsigned 8-bit samples
+{$EXTERNALSYM AUDIO_U8}
+ AUDIO_S8 = $8008; // Signed 8-bit samples
+{$EXTERNALSYM AUDIO_S8}
+ AUDIO_U16LSB = $0010; // Unsigned 16-bit samples
+{$EXTERNALSYM AUDIO_U16LSB}
+ AUDIO_S16LSB = $8010; // Signed 16-bit samples
+{$EXTERNALSYM AUDIO_S16LSB}
+ AUDIO_U16MSB = $1010; // As above, but big-endian byte order
+{$EXTERNALSYM AUDIO_U16MSB}
+ AUDIO_S16MSB = $9010; // As above, but big-endian byte order
+{$EXTERNALSYM AUDIO_S16MSB}
+ AUDIO_U16 = AUDIO_U16LSB;
+{$EXTERNALSYM AUDIO_U16}
+ AUDIO_S16 = AUDIO_S16LSB;
+{$EXTERNALSYM AUDIO_S16}
+
+
+ // SDL_cdrom.h constants
+ // The maximum number of CD-ROM tracks on a disk
+ SDL_MAX_TRACKS = 99;
+{$EXTERNALSYM SDL_MAX_TRACKS}
+ // The types of CD-ROM track possible
+ SDL_AUDIO_TRACK = $00;
+{$EXTERNALSYM SDL_AUDIO_TRACK}
+ SDL_DATA_TRACK = $04;
+{$EXTERNALSYM SDL_DATA_TRACK}
+
+ // Conversion functions from frames to Minute/Second/Frames and vice versa
+ CD_FPS = 75;
+{$EXTERNALSYM CD_FPS}
+ // SDL_byteorder.h constants
+ // The two types of endianness
+ SDL_LIL_ENDIAN = 1234;
+{$EXTERNALSYM SDL_LIL_ENDIAN}
+ SDL_BIG_ENDIAN = 4321;
+{$EXTERNALSYM SDL_BIG_ENDIAN}
+
+{$IFDEF IA32}
+
+ SDL_BYTEORDER = SDL_LIL_ENDIAN;
+{$EXTERNALSYM SDL_BYTEORDER}
+ // Native audio byte ordering
+ AUDIO_U16SYS = AUDIO_U16LSB;
+{$EXTERNALSYM AUDIO_U16SYS}
+ AUDIO_S16SYS = AUDIO_S16LSB;
+{$EXTERNALSYM AUDIO_S16SYS}
+
+{$ELSE}
+
+ SDL_BYTEORDER = SDL_BIG_ENDIAN;
+{$EXTERNALSYM SDL_BYTEORDER}
+ // Native audio byte ordering
+ AUDIO_U16SYS = AUDIO_U16MSB;
+{$EXTERNALSYM AUDIO_U16SYS}
+ AUDIO_S16SYS = AUDIO_S16MSB;
+{$EXTERNALSYM AUDIO_S16SYS}
+
+{$ENDIF}
+
+
+ SDL_MIX_MAXVOLUME = 128;
+{$EXTERNALSYM SDL_MIX_MAXVOLUME}
+
+ // SDL_joystick.h constants
+ MAX_JOYSTICKS = 2; // only 2 are supported in the multimedia API
+{$EXTERNALSYM MAX_JOYSTICKS}
+ MAX_AXES = 6; // each joystick can have up to 6 axes
+{$EXTERNALSYM MAX_AXES}
+ MAX_BUTTONS = 32; // and 32 buttons
+{$EXTERNALSYM MAX_BUTTONS}
+ AXIS_MIN = -32768; // minimum value for axis coordinate
+{$EXTERNALSYM AXIS_MIN}
+ AXIS_MAX = 32767; // maximum value for axis coordinate
+{$EXTERNALSYM AXIS_MAX}
+ JOY_AXIS_THRESHOLD = (((AXIS_MAX) - (AXIS_MIN)) / 100); // 1% motion
+{$EXTERNALSYM JOY_AXIS_THRESHOLD}
+ //JOY_BUTTON_FLAG(n) (1<<n)
+ // array to hold joystick ID values
+ //static UInt SYS_JoystickID[MAX_JOYSTICKS];
+ //static JOYCAPS SYS_Joystick[MAX_JOYSTICKS];
+
+ { Get the current state of a POV hat on a joystick
+ The return value is one of the following positions: }
+ SDL_HAT_CENTERED = $00;
+{$EXTERNALSYM SDL_HAT_CENTERED}
+ SDL_HAT_UP = $01;
+{$EXTERNALSYM SDL_HAT_UP}
+ SDL_HAT_RIGHT = $02;
+{$EXTERNALSYM SDL_HAT_RIGHT}
+ SDL_HAT_DOWN = $04;
+{$EXTERNALSYM SDL_HAT_DOWN}
+ SDL_HAT_LEFT = $08;
+{$EXTERNALSYM SDL_HAT_LEFT}
+ SDL_HAT_RIGHTUP = SDL_HAT_RIGHT or SDL_HAT_UP;
+{$EXTERNALSYM SDL_HAT_RIGHTUP}
+ SDL_HAT_RIGHTDOWN = SDL_HAT_RIGHT or SDL_HAT_DOWN;
+{$EXTERNALSYM SDL_HAT_RIGHTDOWN}
+ SDL_HAT_LEFTUP = SDL_HAT_LEFT or SDL_HAT_UP;
+{$EXTERNALSYM SDL_HAT_LEFTUP}
+ SDL_HAT_LEFTDOWN = SDL_HAT_LEFT or SDL_HAT_DOWN;
+{$EXTERNALSYM SDL_HAT_LEFTDOWN}
+
+ // SDL_events.h constants
+ SDL_NOEVENT = 0; // Unused (do not remove)
+{$EXTERNALSYM SDL_NOEVENT}
+ SDL_ACTIVEEVENT = 1; // Application loses/gains visibility
+{$EXTERNALSYM SDL_ACTIVEEVENT}
+ SDL_KEYDOWN = 2; // Keys pressed
+{$EXTERNALSYM SDL_KEYDOWN}
+ SDL_KEYUP = 3; // Keys released
+{$EXTERNALSYM SDL_KEYUP}
+ SDL_MOUSEMOTION = 4; // Mouse moved
+{$EXTERNALSYM SDL_MOUSEMOTION}
+ SDL_MOUSEBUTTONDOWN = 5; // Mouse button pressed
+{$EXTERNALSYM SDL_MOUSEBUTTONDOWN}
+ SDL_MOUSEBUTTONUP = 6; // Mouse button released
+{$EXTERNALSYM SDL_MOUSEBUTTONUP}
+ SDL_JOYAXISMOTION = 7; // Joystick axis motion
+{$EXTERNALSYM SDL_JOYAXISMOTION}
+ SDL_JOYBALLMOTION = 8; // Joystick trackball motion
+{$EXTERNALSYM SDL_JOYBALLMOTION}
+ SDL_JOYHATMOTION = 9; // Joystick hat position change
+{$EXTERNALSYM SDL_JOYHATMOTION}
+ SDL_JOYBUTTONDOWN = 10; // Joystick button pressed
+{$EXTERNALSYM SDL_JOYBUTTONDOWN}
+ SDL_JOYBUTTONUP = 11; // Joystick button released
+{$EXTERNALSYM SDL_JOYBUTTONUP}
+ SDL_QUITEV = 12; // User-requested quit ( Changed due to procedure conflict )
+{$EXTERNALSYM SDL_QUIT}
+ SDL_SYSWMEVENT = 13; // System specific event
+{$EXTERNALSYM SDL_SYSWMEVENT}
+ SDL_EVENT_RESERVEDA = 14; // Reserved for future use..
+{$EXTERNALSYM SDL_EVENT_RESERVEDA}
+ SDL_EVENT_RESERVED = 15; // Reserved for future use..
+{$EXTERNALSYM SDL_EVENT_RESERVED}
+ SDL_VIDEORESIZE = 16; // User resized video mode
+{$EXTERNALSYM SDL_VIDEORESIZE}
+ SDL_VIDEOEXPOSE = 17; // Screen needs to be redrawn
+{$EXTERNALSYM SDL_VIDEOEXPOSE}
+ SDL_EVENT_RESERVED2 = 18; // Reserved for future use..
+{$EXTERNALSYM SDL_EVENT_RESERVED2}
+ SDL_EVENT_RESERVED3 = 19; // Reserved for future use..
+{$EXTERNALSYM SDL_EVENT_RESERVED3}
+ SDL_EVENT_RESERVED4 = 20; // Reserved for future use..
+{$EXTERNALSYM SDL_EVENT_RESERVED4}
+ SDL_EVENT_RESERVED5 = 21; // Reserved for future use..
+{$EXTERNALSYM SDL_EVENT_RESERVED5}
+ SDL_EVENT_RESERVED6 = 22; // Reserved for future use..
+{$EXTERNALSYM SDL_EVENT_RESERVED6}
+ SDL_EVENT_RESERVED7 = 23; // Reserved for future use..
+{$EXTERNALSYM SDL_EVENT_RESERVED7}
+ // Events SDL_USEREVENT through SDL_MAXEVENTS-1 are for your use
+ SDL_USEREVENT = 24;
+{$EXTERNALSYM SDL_USEREVENT}
+ // This last event is only for bounding internal arrays
+ // It is the number of bits in the event mask datatype -- UInt32
+ SDL_NUMEVENTS = 32;
+{$EXTERNALSYM SDL_NUMEVENTS}
+
+ SDL_ALLEVENTS = $FFFFFFFF;
+{$EXTERNALSYM SDL_ALLEVENTS}
+
+ SDL_ACTIVEEVENTMASK = 1 shl SDL_ACTIVEEVENT;
+{$EXTERNALSYM SDL_ACTIVEEVENTMASK}
+ SDL_KEYDOWNMASK = 1 shl SDL_KEYDOWN;
+{$EXTERNALSYM SDL_KEYDOWNMASK}
+ SDL_KEYUPMASK = 1 shl SDL_KEYUP;
+{$EXTERNALSYM SDL_KEYUPMASK}
+ SDL_MOUSEMOTIONMASK = 1 shl SDL_MOUSEMOTION;
+{$EXTERNALSYM SDL_MOUSEMOTIONMASK}
+ SDL_MOUSEBUTTONDOWNMASK = 1 shl SDL_MOUSEBUTTONDOWN;
+{$EXTERNALSYM SDL_MOUSEBUTTONDOWNMASK}
+ SDL_MOUSEBUTTONUPMASK = 1 shl SDL_MOUSEBUTTONUP;
+{$EXTERNALSYM SDL_MOUSEBUTTONUPMASK}
+ SDL_MOUSEEVENTMASK = 1 shl SDL_MOUSEMOTION or
+ 1 shl SDL_MOUSEBUTTONDOWN or
+ 1 shl SDL_MOUSEBUTTONUP;
+{$EXTERNALSYM SDL_MOUSEEVENTMASK}
+ SDL_JOYAXISMOTIONMASK = 1 shl SDL_JOYAXISMOTION;
+{$EXTERNALSYM SDL_JOYAXISMOTIONMASK}
+ SDL_JOYBALLMOTIONMASK = 1 shl SDL_JOYBALLMOTION;
+{$EXTERNALSYM SDL_JOYBALLMOTIONMASK}
+ SDL_JOYHATMOTIONMASK = 1 shl SDL_JOYHATMOTION;
+{$EXTERNALSYM SDL_JOYHATMOTIONMASK}
+ SDL_JOYBUTTONDOWNMASK = 1 shl SDL_JOYBUTTONDOWN;
+{$EXTERNALSYM SDL_JOYBUTTONDOWNMASK}
+ SDL_JOYBUTTONUPMASK = 1 shl SDL_JOYBUTTONUP;
+{$EXTERNALSYM SDL_JOYBUTTONUPMASK}
+ SDL_JOYEVENTMASK = 1 shl SDL_JOYAXISMOTION or
+ 1 shl SDL_JOYBALLMOTION or
+ 1 shl SDL_JOYHATMOTION or
+ 1 shl SDL_JOYBUTTONDOWN or
+ 1 shl SDL_JOYBUTTONUP;
+{$EXTERNALSYM SDL_JOYEVENTMASK}
+ SDL_VIDEORESIZEMASK = 1 shl SDL_VIDEORESIZE;
+{$EXTERNALSYM SDL_VIDEORESIZEMASK}
+ SDL_QUITMASK = 1 shl SDL_QUITEV;
+{$EXTERNALSYM SDL_QUITMASK}
+ SDL_SYSWMEVENTMASK = 1 shl SDL_SYSWMEVENT;
+{$EXTERNALSYM SDL_SYSWMEVENTMASK}
+
+ { This function allows you to set the state of processing certain events.
+ If 'state' is set to SDL_IGNORE, that event will be automatically dropped
+ from the event queue and will not event be filtered.
+ If 'state' is set to SDL_ENABLE, that event will be processed normally.
+ If 'state' is set to SDL_QUERY, SDL_EventState() will return the
+ current processing state of the specified event. }
+
+ SDL_QUERY = -1;
+{$EXTERNALSYM SDL_QUERY}
+ SDL_IGNORE = 0;
+{$EXTERNALSYM SDL_IGNORE}
+ SDL_DISABLE = 0;
+{$EXTERNALSYM SDL_DISABLE}
+ SDL_ENABLE = 1;
+{$EXTERNALSYM SDL_ENABLE}
+
+ //SDL_keyboard.h constants
+ // This is the mask which refers to all hotkey bindings
+ SDL_ALL_HOTKEYS = $FFFFFFFF;
+{$EXTERNALSYM SDL_ALL_HOTKEYS}
+
+{ Enable/Disable keyboard repeat. Keyboard repeat defaults to off.
+ 'delay' is the initial delay in ms between the time when a key is
+ pressed, and keyboard repeat begins.
+ 'interval' is the time in ms between keyboard repeat events. }
+
+ SDL_DEFAULT_REPEAT_DELAY = 500;
+{$EXTERNALSYM SDL_DEFAULT_REPEAT_DELAY}
+ SDL_DEFAULT_REPEAT_INTERVAL = 30;
+{$EXTERNALSYM SDL_DEFAULT_REPEAT_INTERVAL}
+
+ // The keyboard syms have been cleverly chosen to map to ASCII
+ SDLK_UNKNOWN = 0;
+{$EXTERNALSYM SDLK_UNKNOWN}
+ SDLK_FIRST = 0;
+{$EXTERNALSYM SDLK_FIRST}
+ SDLK_BACKSPACE = 8;
+{$EXTERNALSYM SDLK_BACKSPACE}
+ SDLK_TAB = 9;
+{$EXTERNALSYM SDLK_TAB}
+ SDLK_CLEAR = 12;
+{$EXTERNALSYM SDLK_CLEAR}
+ SDLK_RETURN = 13;
+{$EXTERNALSYM SDLK_RETURN}
+ SDLK_PAUSE = 19;
+{$EXTERNALSYM SDLK_PAUSE}
+ SDLK_ESCAPE = 27;
+{$EXTERNALSYM SDLK_ESCAPE}
+ SDLK_SPACE = 32;
+{$EXTERNALSYM SDLK_SPACE}
+ SDLK_EXCLAIM = 33;
+{$EXTERNALSYM SDLK_EXCLAIM}
+ SDLK_QUOTEDBL = 34;
+{$EXTERNALSYM SDLK_QUOTEDBL}
+ SDLK_HASH = 35;
+{$EXTERNALSYM SDLK_HASH}
+ SDLK_DOLLAR = 36;
+{$EXTERNALSYM SDLK_DOLLAR}
+ SDLK_AMPERSAND = 38;
+{$EXTERNALSYM SDLK_AMPERSAND}
+ SDLK_QUOTE = 39;
+{$EXTERNALSYM SDLK_QUOTE}
+ SDLK_LEFTPAREN = 40;
+{$EXTERNALSYM SDLK_LEFTPAREN}
+ SDLK_RIGHTPAREN = 41;
+{$EXTERNALSYM SDLK_RIGHTPAREN}
+ SDLK_ASTERISK = 42;
+{$EXTERNALSYM SDLK_ASTERISK}
+ SDLK_PLUS = 43;
+{$EXTERNALSYM SDLK_PLUS}
+ SDLK_COMMA = 44;
+{$EXTERNALSYM SDLK_COMMA}
+ SDLK_MINUS = 45;
+{$EXTERNALSYM SDLK_MINUS}
+ SDLK_PERIOD = 46;
+{$EXTERNALSYM SDLK_PERIOD}
+ SDLK_SLASH = 47;
+{$EXTERNALSYM SDLK_SLASH}
+ SDLK_0 = 48;
+{$EXTERNALSYM SDLK_0}
+ SDLK_1 = 49;
+{$EXTERNALSYM SDLK_1}
+ SDLK_2 = 50;
+{$EXTERNALSYM SDLK_2}
+ SDLK_3 = 51;
+{$EXTERNALSYM SDLK_3}
+ SDLK_4 = 52;
+{$EXTERNALSYM SDLK_4}
+ SDLK_5 = 53;
+{$EXTERNALSYM SDLK_5}
+ SDLK_6 = 54;
+{$EXTERNALSYM SDLK_6}
+ SDLK_7 = 55;
+{$EXTERNALSYM SDLK_7}
+ SDLK_8 = 56;
+{$EXTERNALSYM SDLK_8}
+ SDLK_9 = 57;
+{$EXTERNALSYM SDLK_9}
+ SDLK_COLON = 58;
+{$EXTERNALSYM SDLK_COLON}
+ SDLK_SEMICOLON = 59;
+{$EXTERNALSYM SDLK_SEMICOLON}
+ SDLK_LESS = 60;
+{$EXTERNALSYM SDLK_LESS}
+ SDLK_EQUALS = 61;
+{$EXTERNALSYM SDLK_EQUALS}
+ SDLK_GREATER = 62;
+{$EXTERNALSYM SDLK_GREATER}
+ SDLK_QUESTION = 63;
+{$EXTERNALSYM SDLK_QUESTION}
+ SDLK_AT = 64;
+{$EXTERNALSYM SDLK_AT}
+
+ { Skip uppercase letters }
+
+ SDLK_LEFTBRACKET = 91;
+{$EXTERNALSYM SDLK_LEFTBRACKET}
+ SDLK_BACKSLASH = 92;
+{$EXTERNALSYM SDLK_BACKSLASH}
+ SDLK_RIGHTBRACKET = 93;
+{$EXTERNALSYM SDLK_RIGHTBRACKET}
+ SDLK_CARET = 94;
+{$EXTERNALSYM SDLK_CARET}
+ SDLK_UNDERSCORE = 95;
+{$EXTERNALSYM SDLK_UNDERSCORE}
+ SDLK_BACKQUOTE = 96;
+{$EXTERNALSYM SDLK_BACKQUOTE}
+ SDLK_a = 97;
+{$EXTERNALSYM SDLK_a}
+ SDLK_b = 98;
+{$EXTERNALSYM SDLK_b}
+ SDLK_c = 99;
+{$EXTERNALSYM SDLK_c}
+ SDLK_d = 100;
+{$EXTERNALSYM SDLK_d}
+ SDLK_e = 101;
+{$EXTERNALSYM SDLK_e}
+ SDLK_f = 102;
+{$EXTERNALSYM SDLK_f}
+ SDLK_g = 103;
+{$EXTERNALSYM SDLK_g}
+ SDLK_h = 104;
+{$EXTERNALSYM SDLK_h}
+ SDLK_i = 105;
+{$EXTERNALSYM SDLK_i}
+ SDLK_j = 106;
+{$EXTERNALSYM SDLK_j}
+ SDLK_k = 107;
+{$EXTERNALSYM SDLK_k}
+ SDLK_l = 108;
+{$EXTERNALSYM SDLK_l}
+ SDLK_m = 109;
+{$EXTERNALSYM SDLK_m}
+ SDLK_n = 110;
+{$EXTERNALSYM SDLK_n}
+ SDLK_o = 111;
+{$EXTERNALSYM SDLK_o}
+ SDLK_p = 112;
+{$EXTERNALSYM SDLK_p}
+ SDLK_q = 113;
+{$EXTERNALSYM SDLK_q}
+ SDLK_r = 114;
+{$EXTERNALSYM SDLK_r}
+ SDLK_s = 115;
+{$EXTERNALSYM SDLK_s}
+ SDLK_t = 116;
+{$EXTERNALSYM SDLK_t}
+ SDLK_u = 117;
+{$EXTERNALSYM SDLK_u}
+ SDLK_v = 118;
+{$EXTERNALSYM SDLK_v}
+ SDLK_w = 119;
+{$EXTERNALSYM SDLK_w}
+ SDLK_x = 120;
+{$EXTERNALSYM SDLK_x}
+ SDLK_y = 121;
+{$EXTERNALSYM SDLK_y}
+ SDLK_z = 122;
+{$EXTERNALSYM SDLK_z}
+ SDLK_DELETE = 127;
+{$EXTERNALSYM SDLK_DELETE}
+ // End of ASCII mapped keysyms
+
+ // International keyboard syms
+ SDLK_WORLD_0 = 160; // 0xA0
+{$EXTERNALSYM SDLK_WORLD_0}
+ SDLK_WORLD_1 = 161;
+{$EXTERNALSYM SDLK_WORLD_1}
+ SDLK_WORLD_2 = 162;
+{$EXTERNALSYM SDLK_WORLD_2}
+ SDLK_WORLD_3 = 163;
+{$EXTERNALSYM SDLK_WORLD_3}
+ SDLK_WORLD_4 = 164;
+{$EXTERNALSYM SDLK_WORLD_4}
+ SDLK_WORLD_5 = 165;
+{$EXTERNALSYM SDLK_WORLD_5}
+ SDLK_WORLD_6 = 166;
+{$EXTERNALSYM SDLK_WORLD_6}
+ SDLK_WORLD_7 = 167;
+{$EXTERNALSYM SDLK_WORLD_7}
+ SDLK_WORLD_8 = 168;
+{$EXTERNALSYM SDLK_WORLD_8}
+ SDLK_WORLD_9 = 169;
+{$EXTERNALSYM SDLK_WORLD_9}
+ SDLK_WORLD_10 = 170;
+{$EXTERNALSYM SDLK_WORLD_10}
+ SDLK_WORLD_11 = 171;
+{$EXTERNALSYM SDLK_WORLD_11}
+ SDLK_WORLD_12 = 172;
+{$EXTERNALSYM SDLK_WORLD_12}
+ SDLK_WORLD_13 = 173;
+{$EXTERNALSYM SDLK_WORLD_13}
+ SDLK_WORLD_14 = 174;
+{$EXTERNALSYM SDLK_WORLD_14}
+ SDLK_WORLD_15 = 175;
+{$EXTERNALSYM SDLK_WORLD_15}
+ SDLK_WORLD_16 = 176;
+{$EXTERNALSYM SDLK_WORLD_16}
+ SDLK_WORLD_17 = 177;
+{$EXTERNALSYM SDLK_WORLD_17}
+ SDLK_WORLD_18 = 178;
+{$EXTERNALSYM SDLK_WORLD_18}
+ SDLK_WORLD_19 = 179;
+{$EXTERNALSYM SDLK_WORLD_19}
+ SDLK_WORLD_20 = 180;
+{$EXTERNALSYM SDLK_WORLD_20}
+ SDLK_WORLD_21 = 181;
+{$EXTERNALSYM SDLK_WORLD_21}
+ SDLK_WORLD_22 = 182;
+{$EXTERNALSYM SDLK_WORLD_22}
+ SDLK_WORLD_23 = 183;
+{$EXTERNALSYM SDLK_WORLD_23}
+ SDLK_WORLD_24 = 184;
+{$EXTERNALSYM SDLK_WORLD_24}
+ SDLK_WORLD_25 = 185;
+{$EXTERNALSYM SDLK_WORLD_25}
+ SDLK_WORLD_26 = 186;
+{$EXTERNALSYM SDLK_WORLD_26}
+ SDLK_WORLD_27 = 187;
+{$EXTERNALSYM SDLK_WORLD_27}
+ SDLK_WORLD_28 = 188;
+{$EXTERNALSYM SDLK_WORLD_28}
+ SDLK_WORLD_29 = 189;
+{$EXTERNALSYM SDLK_WORLD_29}
+ SDLK_WORLD_30 = 190;
+{$EXTERNALSYM SDLK_WORLD_30}
+ SDLK_WORLD_31 = 191;
+{$EXTERNALSYM SDLK_WORLD_31}
+ SDLK_WORLD_32 = 192;
+{$EXTERNALSYM SDLK_WORLD_32}
+ SDLK_WORLD_33 = 193;
+{$EXTERNALSYM SDLK_WORLD_33}
+ SDLK_WORLD_34 = 194;
+{$EXTERNALSYM SDLK_WORLD_34}
+ SDLK_WORLD_35 = 195;
+{$EXTERNALSYM SDLK_WORLD_35}
+ SDLK_WORLD_36 = 196;
+{$EXTERNALSYM SDLK_WORLD_36}
+ SDLK_WORLD_37 = 197;
+{$EXTERNALSYM SDLK_WORLD_37}
+ SDLK_WORLD_38 = 198;
+{$EXTERNALSYM SDLK_WORLD_38}
+ SDLK_WORLD_39 = 199;
+{$EXTERNALSYM SDLK_WORLD_39}
+ SDLK_WORLD_40 = 200;
+{$EXTERNALSYM SDLK_WORLD_40}
+ SDLK_WORLD_41 = 201;
+{$EXTERNALSYM SDLK_WORLD_41}
+ SDLK_WORLD_42 = 202;
+{$EXTERNALSYM SDLK_WORLD_42}
+ SDLK_WORLD_43 = 203;
+{$EXTERNALSYM SDLK_WORLD_43}
+ SDLK_WORLD_44 = 204;
+{$EXTERNALSYM SDLK_WORLD_44}
+ SDLK_WORLD_45 = 205;
+{$EXTERNALSYM SDLK_WORLD_45}
+ SDLK_WORLD_46 = 206;
+{$EXTERNALSYM SDLK_WORLD_46}
+ SDLK_WORLD_47 = 207;
+{$EXTERNALSYM SDLK_WORLD_47}
+ SDLK_WORLD_48 = 208;
+{$EXTERNALSYM SDLK_WORLD_48}
+ SDLK_WORLD_49 = 209;
+{$EXTERNALSYM SDLK_WORLD_49}
+ SDLK_WORLD_50 = 210;
+{$EXTERNALSYM SDLK_WORLD_50}
+ SDLK_WORLD_51 = 211;
+{$EXTERNALSYM SDLK_WORLD_51}
+ SDLK_WORLD_52 = 212;
+{$EXTERNALSYM SDLK_WORLD_52}
+ SDLK_WORLD_53 = 213;
+{$EXTERNALSYM SDLK_WORLD_53}
+ SDLK_WORLD_54 = 214;
+{$EXTERNALSYM SDLK_WORLD_54}
+ SDLK_WORLD_55 = 215;
+{$EXTERNALSYM SDLK_WORLD_55}
+ SDLK_WORLD_56 = 216;
+{$EXTERNALSYM SDLK_WORLD_56}
+ SDLK_WORLD_57 = 217;
+{$EXTERNALSYM SDLK_WORLD_57}
+ SDLK_WORLD_58 = 218;
+{$EXTERNALSYM SDLK_WORLD_58}
+ SDLK_WORLD_59 = 219;
+{$EXTERNALSYM SDLK_WORLD_59}
+ SDLK_WORLD_60 = 220;
+{$EXTERNALSYM SDLK_WORLD_60}
+ SDLK_WORLD_61 = 221;
+{$EXTERNALSYM SDLK_WORLD_61}
+ SDLK_WORLD_62 = 222;
+{$EXTERNALSYM SDLK_WORLD_62}
+ SDLK_WORLD_63 = 223;
+{$EXTERNALSYM SDLK_WORLD_63}
+ SDLK_WORLD_64 = 224;
+{$EXTERNALSYM SDLK_WORLD_64}
+ SDLK_WORLD_65 = 225;
+{$EXTERNALSYM SDLK_WORLD_65}
+ SDLK_WORLD_66 = 226;
+{$EXTERNALSYM SDLK_WORLD_66}
+ SDLK_WORLD_67 = 227;
+{$EXTERNALSYM SDLK_WORLD_67}
+ SDLK_WORLD_68 = 228;
+{$EXTERNALSYM SDLK_WORLD_68}
+ SDLK_WORLD_69 = 229;
+{$EXTERNALSYM SDLK_WORLD_69}
+ SDLK_WORLD_70 = 230;
+{$EXTERNALSYM SDLK_WORLD_70}
+ SDLK_WORLD_71 = 231;
+{$EXTERNALSYM SDLK_WORLD_71}
+ SDLK_WORLD_72 = 232;
+{$EXTERNALSYM SDLK_WORLD_72}
+ SDLK_WORLD_73 = 233;
+{$EXTERNALSYM SDLK_WORLD_73}
+ SDLK_WORLD_74 = 234;
+{$EXTERNALSYM SDLK_WORLD_74}
+ SDLK_WORLD_75 = 235;
+{$EXTERNALSYM SDLK_WORLD_75}
+ SDLK_WORLD_76 = 236;
+{$EXTERNALSYM SDLK_WORLD_76}
+ SDLK_WORLD_77 = 237;
+{$EXTERNALSYM SDLK_WORLD_77}
+ SDLK_WORLD_78 = 238;
+{$EXTERNALSYM SDLK_WORLD_78}
+ SDLK_WORLD_79 = 239;
+{$EXTERNALSYM SDLK_WORLD_79}
+ SDLK_WORLD_80 = 240;
+{$EXTERNALSYM SDLK_WORLD_80}
+ SDLK_WORLD_81 = 241;
+{$EXTERNALSYM SDLK_WORLD_81}
+ SDLK_WORLD_82 = 242;
+{$EXTERNALSYM SDLK_WORLD_82}
+ SDLK_WORLD_83 = 243;
+{$EXTERNALSYM SDLK_WORLD_83}
+ SDLK_WORLD_84 = 244;
+{$EXTERNALSYM SDLK_WORLD_84}
+ SDLK_WORLD_85 = 245;
+{$EXTERNALSYM SDLK_WORLD_85}
+ SDLK_WORLD_86 = 246;
+{$EXTERNALSYM SDLK_WORLD_86}
+ SDLK_WORLD_87 = 247;
+{$EXTERNALSYM SDLK_WORLD_87}
+ SDLK_WORLD_88 = 248;
+{$EXTERNALSYM SDLK_WORLD_88}
+ SDLK_WORLD_89 = 249;
+{$EXTERNALSYM SDLK_WORLD_89}
+ SDLK_WORLD_90 = 250;
+{$EXTERNALSYM SDLK_WORLD_90}
+ SDLK_WORLD_91 = 251;
+{$EXTERNALSYM SDLK_WORLD_91}
+ SDLK_WORLD_92 = 252;
+{$EXTERNALSYM SDLK_WORLD_92}
+ SDLK_WORLD_93 = 253;
+{$EXTERNALSYM SDLK_WORLD_93}
+ SDLK_WORLD_94 = 254;
+{$EXTERNALSYM SDLK_WORLD_94}
+ SDLK_WORLD_95 = 255; // 0xFF
+{$EXTERNALSYM SDLK_WORLD_95}
+
+ // Numeric keypad
+ SDLK_KP0 = 256;
+{$EXTERNALSYM SDLK_KP0}
+ SDLK_KP1 = 257;
+{$EXTERNALSYM SDLK_KP1}
+ SDLK_KP2 = 258;
+{$EXTERNALSYM SDLK_KP2}
+ SDLK_KP3 = 259;
+{$EXTERNALSYM SDLK_KP3}
+ SDLK_KP4 = 260;
+{$EXTERNALSYM SDLK_KP4}
+ SDLK_KP5 = 261;
+{$EXTERNALSYM SDLK_KP5}
+ SDLK_KP6 = 262;
+{$EXTERNALSYM SDLK_KP6}
+ SDLK_KP7 = 263;
+{$EXTERNALSYM SDLK_KP7}
+ SDLK_KP8 = 264;
+{$EXTERNALSYM SDLK_KP8}
+ SDLK_KP9 = 265;
+{$EXTERNALSYM SDLK_KP9}
+ SDLK_KP_PERIOD = 266;
+{$EXTERNALSYM SDLK_KP_PERIOD}
+ SDLK_KP_DIVIDE = 267;
+{$EXTERNALSYM SDLK_KP_DIVIDE}
+ SDLK_KP_MULTIPLY = 268;
+{$EXTERNALSYM SDLK_KP_MULTIPLY}
+ SDLK_KP_MINUS = 269;
+{$EXTERNALSYM SDLK_KP_MINUS}
+ SDLK_KP_PLUS = 270;
+{$EXTERNALSYM SDLK_KP_PLUS}
+ SDLK_KP_ENTER = 271;
+{$EXTERNALSYM SDLK_KP_ENTER}
+ SDLK_KP_EQUALS = 272;
+{$EXTERNALSYM SDLK_KP_EQUALS}
+
+ // Arrows + Home/End pad
+ SDLK_UP = 273;
+{$EXTERNALSYM SDLK_UP}
+ SDLK_DOWN = 274;
+{$EXTERNALSYM SDLK_DOWN}
+ SDLK_RIGHT = 275;
+{$EXTERNALSYM SDLK_RIGHT}
+ SDLK_LEFT = 276;
+{$EXTERNALSYM SDLK_LEFT}
+ SDLK_INSERT = 277;
+{$EXTERNALSYM SDLK_INSERT}
+ SDLK_HOME = 278;
+{$EXTERNALSYM SDLK_HOME}
+ SDLK_END = 279;
+{$EXTERNALSYM SDLK_END}
+ SDLK_PAGEUP = 280;
+{$EXTERNALSYM SDLK_PAGEUP}
+ SDLK_PAGEDOWN = 281;
+{$EXTERNALSYM SDLK_PAGEDOWN}
+
+ // Function keys
+ SDLK_F1 = 282;
+{$EXTERNALSYM SDLK_F1}
+ SDLK_F2 = 283;
+{$EXTERNALSYM SDLK_F2}
+ SDLK_F3 = 284;
+{$EXTERNALSYM SDLK_F3}
+ SDLK_F4 = 285;
+{$EXTERNALSYM SDLK_F4}
+ SDLK_F5 = 286;
+{$EXTERNALSYM SDLK_F5}
+ SDLK_F6 = 287;
+{$EXTERNALSYM SDLK_F6}
+ SDLK_F7 = 288;
+{$EXTERNALSYM SDLK_F7}
+ SDLK_F8 = 289;
+{$EXTERNALSYM SDLK_F8}
+ SDLK_F9 = 290;
+{$EXTERNALSYM SDLK_F9}
+ SDLK_F10 = 291;
+{$EXTERNALSYM SDLK_F10}
+ SDLK_F11 = 292;
+{$EXTERNALSYM SDLK_F11}
+ SDLK_F12 = 293;
+{$EXTERNALSYM SDLK_F12}
+ SDLK_F13 = 294;
+{$EXTERNALSYM SDLK_F13}
+ SDLK_F14 = 295;
+{$EXTERNALSYM SDLK_F14}
+ SDLK_F15 = 296;
+{$EXTERNALSYM SDLK_F15}
+
+ // Key state modifier keys
+ SDLK_NUMLOCK = 300;
+{$EXTERNALSYM SDLK_NUMLOCK}
+ SDLK_CAPSLOCK = 301;
+{$EXTERNALSYM SDLK_CAPSLOCK}
+ SDLK_SCROLLOCK = 302;
+{$EXTERNALSYM SDLK_SCROLLOCK}
+ SDLK_RSHIFT = 303;
+{$EXTERNALSYM SDLK_RSHIFT}
+ SDLK_LSHIFT = 304;
+{$EXTERNALSYM SDLK_LSHIFT}
+ SDLK_RCTRL = 305;
+{$EXTERNALSYM SDLK_RCTRL}
+ SDLK_LCTRL = 306;
+{$EXTERNALSYM SDLK_LCTRL}
+ SDLK_RALT = 307;
+{$EXTERNALSYM SDLK_RALT}
+ SDLK_LALT = 308;
+{$EXTERNALSYM SDLK_LALT}
+ SDLK_RMETA = 309;
+{$EXTERNALSYM SDLK_RMETA}
+ SDLK_LMETA = 310;
+{$EXTERNALSYM SDLK_LMETA}
+ SDLK_LSUPER = 311; // Left "Windows" key
+{$EXTERNALSYM SDLK_LSUPER}
+ SDLK_RSUPER = 312; // Right "Windows" key
+{$EXTERNALSYM SDLK_RSUPER}
+ SDLK_MODE = 313; // "Alt Gr" key
+{$EXTERNALSYM SDLK_MODE}
+ SDLK_COMPOSE = 314; // Multi-key compose key
+{$EXTERNALSYM SDLK_COMPOSE}
+
+ // Miscellaneous function keys
+ SDLK_HELP = 315;
+{$EXTERNALSYM SDLK_HELP}
+ SDLK_PRINT = 316;
+{$EXTERNALSYM SDLK_PRINT}
+ SDLK_SYSREQ = 317;
+{$EXTERNALSYM SDLK_SYSREQ}
+ SDLK_BREAK = 318;
+{$EXTERNALSYM SDLK_BREAK}
+ SDLK_MENU = 319;
+{$EXTERNALSYM SDLK_MENU}
+ SDLK_POWER = 320; // Power Macintosh power key
+{$EXTERNALSYM SDLK_POWER}
+ SDLK_EURO = 321; // Some european keyboards
+{$EXTERNALSYM SDLK_EURO}
+
+{$IFDEF GP2X}
+SDLK_GP2X_UP = 0;
+{$EXTERNALSYM SDLK_GP2X_UP}
+SDLK_GP2X_UPLEFT = 1;
+{$EXTERNALSYM SDLK_GP2X_UPLEFT}
+SDLK_GP2X_LEFT = 2;
+{$EXTERNALSYM SDLK_GP2X_LEFT}
+SDLK_GP2X_DOWNLEFT = 3;
+{$EXTERNALSYM SDLK_GP2X_DOWNLEFT}
+SDLK_GP2X_DOWN = 4;
+{$EXTERNALSYM SDLK_GP2X_DOWN}
+SDLK_GP2X_DOWNRIGHT = 5;
+{$EXTERNALSYM SDLK_GP2X_DOWNRIGHT}
+SDLK_GP2X_RIGHT = 6;
+{$EXTERNALSYM SDLK_GP2X_RIGHT}
+SDLK_GP2X_UPRIGHT = 7;
+{$EXTERNALSYM SDLK_GP2X_UPRIGHT}
+SDLK_GP2X_START = 8;
+{$EXTERNALSYM SDLK_GP2X_START}
+SDLK_GP2X_SELECT = 9;
+{$EXTERNALSYM SDLK_GP2X_SELECT}
+SDLK_GP2X_L = 10;
+{$EXTERNALSYM SDLK_GP2X_L}
+SDLK_GP2X_R = 11;
+{$EXTERNALSYM SDLK_GP2X_R}
+SDLK_GP2X_A = 12;
+{$EXTERNALSYM SDLK_GP2X_A}
+SDLK_GP2X_B = 13;
+{$EXTERNALSYM SDLK_GP2X_B}
+SDLK_GP2X_Y = 14;
+{$EXTERNALSYM SDLK_GP2X_Y}
+SDLK_GP2X_X = 15;
+{$EXTERNALSYM SDLK_GP2X_X}
+SDLK_GP2X_VOLUP = 16;
+{$EXTERNALSYM SDLK_GP2X_VOLUP}
+SDLK_GP2X_VOLDOWN = 17;
+{$EXTERNALSYM SDLK_GP2X_VOLDOWN}
+SDLK_GP2X_CLICK = 18;
+{$EXTERNALSYM SDLK_GP2X_CLICK}
+{$ENDIF}
+
+ // Enumeration of valid key mods (possibly OR'd together)
+ KMOD_NONE = $0000;
+{$EXTERNALSYM KMOD_NONE}
+ KMOD_LSHIFT = $0001;
+{$EXTERNALSYM KMOD_LSHIFT}
+ KMOD_RSHIFT = $0002;
+{$EXTERNALSYM KMOD_RSHIFT}
+ KMOD_LCTRL = $0040;
+{$EXTERNALSYM KMOD_LCTRL}
+ KMOD_RCTRL = $0080;
+{$EXTERNALSYM KMOD_RCTRL}
+ KMOD_LALT = $0100;
+{$EXTERNALSYM KMOD_LALT}
+ KMOD_RALT = $0200;
+{$EXTERNALSYM KMOD_RALT}
+ KMOD_LMETA = $0400;
+{$EXTERNALSYM KMOD_LMETA}
+ KMOD_RMETA = $0800;
+{$EXTERNALSYM KMOD_RMETA}
+ KMOD_NUM = $1000;
+{$EXTERNALSYM KMOD_NUM}
+ KMOD_CAPS = $2000;
+{$EXTERNALSYM KMOD_CAPS}
+ KMOD_MODE = 44000;
+{$EXTERNALSYM KMOD_MODE}
+ KMOD_RESERVED = $8000;
+{$EXTERNALSYM KMOD_RESERVED}
+
+ KMOD_CTRL = (KMOD_LCTRL or KMOD_RCTRL);
+{$EXTERNALSYM KMOD_CTRL}
+ KMOD_SHIFT = (KMOD_LSHIFT or KMOD_RSHIFT);
+{$EXTERNALSYM KMOD_SHIFT}
+ KMOD_ALT = (KMOD_LALT or KMOD_RALT);
+{$EXTERNALSYM KMOD_ALT}
+ KMOD_META = (KMOD_LMETA or KMOD_RMETA);
+{$EXTERNALSYM KMOD_META}
+
+ //SDL_video.h constants
+ // Transparency definitions: These define alpha as the opacity of a surface */
+ SDL_ALPHA_OPAQUE = 255;
+{$EXTERNALSYM SDL_ALPHA_OPAQUE}
+ SDL_ALPHA_TRANSPARENT = 0;
+{$EXTERNALSYM SDL_ALPHA_TRANSPARENT}
+
+ // These are the currently supported flags for the SDL_surface
+ // Available for SDL_CreateRGBSurface() or SDL_SetVideoMode()
+ SDL_SWSURFACE = $00000000; // Surface is in system memory
+{$EXTERNALSYM SDL_SWSURFACE}
+ SDL_HWSURFACE = $00000001; // Surface is in video memory
+{$EXTERNALSYM SDL_HWSURFACE}
+ SDL_ASYNCBLIT = $00000004; // Use asynchronous blits if possible
+{$EXTERNALSYM SDL_ASYNCBLIT}
+ // Available for SDL_SetVideoMode()
+ SDL_ANYFORMAT = $10000000; // Allow any video depth/pixel-format
+{$EXTERNALSYM SDL_ANYFORMAT}
+ SDL_HWPALETTE = $20000000; // Surface has exclusive palette
+{$EXTERNALSYM SDL_HWPALETTE}
+ SDL_DOUBLEBUF = $40000000; // Set up double-buffered video mode
+{$EXTERNALSYM SDL_DOUBLEBUF}
+ SDL_FULLSCREEN = $80000000; // Surface is a full screen display
+{$EXTERNALSYM SDL_FULLSCREEN}
+ SDL_OPENGL = $00000002; // Create an OpenGL rendering context
+{$EXTERNALSYM SDL_OPENGL}
+ SDL_OPENGLBLIT = $00000002; // Create an OpenGL rendering context
+{$EXTERNALSYM SDL_OPENGLBLIT}
+ SDL_RESIZABLE = $00000010; // This video mode may be resized
+{$EXTERNALSYM SDL_RESIZABLE}
+ SDL_NOFRAME = $00000020; // No window caption or edge frame
+{$EXTERNALSYM SDL_NOFRAME}
+ // Used internally (read-only)
+ SDL_HWACCEL = $00000100; // Blit uses hardware acceleration
+{$EXTERNALSYM SDL_HWACCEL}
+ SDL_SRCCOLORKEY = $00001000; // Blit uses a source color key
+{$EXTERNALSYM SDL_SRCCOLORKEY}
+ SDL_RLEACCELOK = $00002000; // Private flag
+{$EXTERNALSYM SDL_RLEACCELOK}
+ SDL_RLEACCEL = $00004000; // Colorkey blit is RLE accelerated
+{$EXTERNALSYM SDL_RLEACCEL}
+ SDL_SRCALPHA = $00010000; // Blit uses source alpha blending
+{$EXTERNALSYM SDL_SRCALPHA}
+ SDL_SRCCLIPPING = $00100000; // Blit uses source clipping
+{$EXTERNALSYM SDL_SRCCLIPPING}
+ SDL_PREALLOC = $01000000; // Surface uses preallocated memory
+{$EXTERNALSYM SDL_PREALLOC}
+
+ { The most common video overlay formats.
+ For an explanation of these pixel formats, see:
+ http://www.webartz.com/fourcc/indexyuv.htm
+
+ For information on the relationship between color spaces, see:
+ http://www.neuro.sfc.keio.ac.jp/~aly/polygon/info/color-space-faq.html }
+
+ SDL_YV12_OVERLAY = $32315659; // Planar mode: Y + V + U (3 planes)
+{$EXTERNALSYM SDL_YV12_OVERLAY}
+ SDL_IYUV_OVERLAY = $56555949; // Planar mode: Y + U + V (3 planes)
+{$EXTERNALSYM SDL_IYUV_OVERLAY}
+ SDL_YUY2_OVERLAY = $32595559; // Packed mode: Y0+U0+Y1+V0 (1 plane)
+{$EXTERNALSYM SDL_YUY2_OVERLAY}
+ SDL_UYVY_OVERLAY = $59565955; // Packed mode: U0+Y0+V0+Y1 (1 plane)
+{$EXTERNALSYM SDL_UYVY_OVERLAY}
+ SDL_YVYU_OVERLAY = $55595659; // Packed mode: Y0+V0+Y1+U0 (1 plane)
+{$EXTERNALSYM SDL_YVYU_OVERLAY}
+
+ // flags for SDL_SetPalette()
+ SDL_LOGPAL = $01;
+{$EXTERNALSYM SDL_LOGPAL}
+ SDL_PHYSPAL = $02;
+{$EXTERNALSYM SDL_PHYSPAL}
+
+ //SDL_mouse.h constants
+ { Used as a mask when testing buttons in buttonstate
+ Button 1: Left mouse button
+ Button 2: Middle mouse button
+ Button 3: Right mouse button
+ Button 4: Mouse Wheel Up
+ Button 5: Mouse Wheel Down
+ }
+ SDL_BUTTON_LEFT = 1;
+{$EXTERNALSYM SDL_BUTTON_LEFT}
+ SDL_BUTTON_MIDDLE = 2;
+{$EXTERNALSYM SDL_BUTTON_MIDDLE}
+ SDL_BUTTON_RIGHT = 3;
+{$EXTERNALSYM SDL_BUTTON_RIGHT}
+ SDL_BUTTON_WHEELUP = 4;
+{$EXTERNALSYM SDL_BUTTON_WHEELUP}
+ SDL_BUTTON_WHEELDOWN = 5;
+{$EXTERNALSYM SDL_BUTTON_WHEELDOWN}
+ SDL_BUTTON_LMASK = SDL_PRESSED shl (SDL_BUTTON_LEFT - 1);
+{$EXTERNALSYM SDL_BUTTON_LMASK}
+ SDL_BUTTON_MMASK = SDL_PRESSED shl (SDL_BUTTON_MIDDLE - 1);
+{$EXTERNALSYM SDL_BUTTON_MMASK}
+ SDL_BUTTON_RMask = SDL_PRESSED shl (SDL_BUTTON_RIGHT - 1);
+{$EXTERNALSYM SDL_BUTTON_RMask}
+
+ // SDL_active.h constants
+ // The available application states
+ SDL_APPMOUSEFOCUS = $01; // The app has mouse coverage
+{$EXTERNALSYM SDL_APPMOUSEFOCUS}
+ SDL_APPINPUTFOCUS = $02; // The app has input focus
+{$EXTERNALSYM SDL_APPINPUTFOCUS}
+ SDL_APPACTIVE = $04; // The application is active
+{$EXTERNALSYM SDL_APPACTIVE}
+
+ // SDL_mutex.h constants
+ // Synchronization functions which can time out return this value
+ // they time out.
+
+ SDL_MUTEX_TIMEDOUT = 1;
+{$EXTERNALSYM SDL_MUTEX_TIMEDOUT}
+
+ // This is the timeout value which corresponds to never time out
+ SDL_MUTEX_MAXWAIT = not Cardinal(0);
+{$EXTERNALSYM SDL_MUTEX_MAXWAIT}
+
+ {TSDL_GrabMode = (
+ SDL_GRAB_QUERY,
+ SDL_GRAB_OFF,
+ SDL_GRAB_ON,
+ SDL_GRAB_FULLSCREEN ); // Used internally}
+ SDL_GRAB_QUERY = -1;
+ SDL_GRAB_OFF = 0;
+ SDL_GRAB_ON = 1;
+ //SDL_GRAB_FULLSCREEN // Used internally
+
+type
+ THandle = Cardinal;
+ //SDL_types.h types
+ // Basic data types
+
+ SDL_Bool = (SDL_FALSE, SDL_TRUE);
+ TSDL_Bool = SDL_Bool;
+
+ PUInt8Array = ^TUInt8Array;
+ PUInt8 = ^UInt8;
+ PPUInt8 = ^PUInt8;
+ UInt8 = Byte;
+{$EXTERNALSYM UInt8}
+ TUInt8Array = array [0..MAXINT shr 1] of UInt8;
+
+ PUInt16 = ^UInt16;
+ UInt16 = word;
+{$EXTERNALSYM UInt16}
+
+ PSInt8 = ^SInt8;
+ SInt8 = Shortint;
+{$EXTERNALSYM SInt8}
+
+ PSInt16 = ^SInt16;
+ SInt16 = smallint;
+{$EXTERNALSYM SInt16}
+
+ PUInt32 = ^UInt32;
+ UInt32 = Cardinal;
+{$EXTERNALSYM UInt32}
+
+ SInt32 = Integer;
+{$EXTERNALSYM SInt32}
+
+ PInt = ^Integer;
+
+ PShortInt = ^ShortInt;
+
+ PUInt64 = ^UInt64;
+ UInt64 = record
+ hi: UInt32;
+ lo: UInt32;
+ end;
+{$EXTERNALSYM UInt64}
+
+ PSInt64 = ^SInt64;
+ SInt64 = record
+ hi: UInt32;
+ lo: UInt32;
+ end;
+{$EXTERNALSYM SInt64}
+
+ TSDL_GrabMode = Integer;
+
+ // SDL_error.h types
+ TSDL_errorcode = (
+ SDL_ENOMEM,
+ SDL_EFREAD,
+ SDL_EFWRITE,
+ SDL_EFSEEK,
+ SDL_LASTERROR);
+
+ SDL_errorcode = TSDL_errorcode;
+{$EXTERNALSYM SDL_errorcode}
+
+ TArg = record
+ case Byte of
+ 0: (value_ptr: Pointer);
+ (* #if 0 means: never
+ 1 : ( value_c : Byte );
+ *)
+ 2: (value_i: Integer);
+ 3: (value_f: double);
+ 4: (buf: array[0..ERR_MAX_STRLEN - 1] of Byte);
+ end;
+
+ PSDL_error = ^TSDL_error;
+ TSDL_error = record
+ { This is a numeric value corresponding to the current error }
+ error: Integer;
+
+ { This is a key used to index into a language hashtable containing
+ internationalized versions of the SDL error messages. If the key
+ is not in the hashtable, or no hashtable is available, the key is
+ used directly as an error message format string. }
+ key: array[0..ERR_MAX_STRLEN - 1] of Byte;
+
+ { These are the arguments for the error functions }
+ argc: Integer;
+ args: array[0..ERR_MAX_ARGS - 1] of TArg;
+ end;
+
+ // SDL_rwops.h types
+ // This is the read/write operation structure -- very basic
+ // some helper types to handle the unions
+ // "packed" is only guessed
+
+ TStdio = record
+ autoclose: Integer;
+ // FILE * is only defined in Kylix so we use a simple Pointer
+ fp: Pointer;
+ end;
+
+ TMem = record
+ base: PUInt8;
+ here: PUInt8;
+ stop: PUInt8;
+ end;
+
+ TUnknown = record
+ data1: Pointer;
+ end;
+
+ // first declare the pointer type
+ PSDL_RWops = ^TSDL_RWops;
+ // now the pointer to function types
+ {$IFNDEF __GPC__}
+ TSeek = function( context: PSDL_RWops; offset: Integer; whence: Integer ): Integer; cdecl;
+ TRead = function( context: PSDL_RWops; Ptr: Pointer; size: Integer; maxnum : Integer ): Integer; cdecl;
+ TWrite = function( context: PSDL_RWops; Ptr: Pointer; size: Integer; num: Integer ): Integer; cdecl;
+ TClose = function( context: PSDL_RWops ): Integer; cdecl;
+ {$ELSE}
+ TSeek = function( context: PSDL_RWops; offset: Integer; whence: Integer ): Integer;
+ TRead = function( context: PSDL_RWops; Ptr: Pointer; size: Integer; maxnum : Integer ): Integer;
+ TWrite = function( context: PSDL_RWops; Ptr: Pointer; size: Integer; num: Integer ): Integer;
+ TClose = function( context: PSDL_RWops ): Integer;
+ {$ENDIF}
+ // the variant record itself
+ TSDL_RWops = record
+ seek: TSeek;
+ read: TRead;
+ write: TWrite;
+ close: TClose;
+ // a keyword as name is not allowed
+ type_: UInt32;
+ // be warned! structure alignment may arise at this point
+ case Integer of
+ 0: (stdio: TStdio);
+ 1: (mem: TMem);
+ 2: (unknown: TUnknown);
+ end;
+
+ SDL_RWops = TSDL_RWops;
+{$EXTERNALSYM SDL_RWops}
+
+
+ // SDL_timer.h types
+ // Function prototype for the timer callback function
+ {$IFNDEF __GPC__}
+ TSDL_TimerCallback = function( interval: UInt32 ): UInt32; cdecl;
+ {$ELSE}
+ TSDL_TimerCallback = function( interval: UInt32 ): UInt32;
+ {$ENDIF}
+
+ { New timer API, supports multiple timers
+ Written by Stephane Peter <megastep@lokigames.com> }
+
+ { Function prototype for the new timer callback function.
+ The callback function is passed the current timer interval and returns
+ the next timer interval. If the returned value is the same as the one
+ passed in, the periodic alarm continues, otherwise a new alarm is
+ scheduled. If the callback returns 0, the periodic alarm is cancelled. }
+ {$IFNDEF __GPC__}
+ TSDL_NewTimerCallback = function( interval: UInt32; param: Pointer ): UInt32; cdecl;
+ {$ELSE}
+ TSDL_NewTimerCallback = function( interval: UInt32; param: Pointer ): UInt32;
+ {$ENDIF}
+
+ // Definition of the timer ID type
+ PSDL_TimerID = ^TSDL_TimerID;
+ TSDL_TimerID = record
+ interval: UInt32;
+ callback: TSDL_NewTimerCallback;
+ param: Pointer;
+ last_alarm: UInt32;
+ next: PSDL_TimerID;
+ end;
+
+ {$IFNDEF __GPC__}
+ TSDL_AudioSpecCallback = procedure( userdata: Pointer; stream: PUInt8; len: Integer ); cdecl;
+ {$ELSE}
+ TSDL_AudioSpecCallback = procedure( userdata: Pointer; stream: PUInt8; len: Integer );
+ {$ENDIF}
+
+ // SDL_audio.h types
+ // The calculated values in this structure are calculated by SDL_OpenAudio()
+ PSDL_AudioSpec = ^TSDL_AudioSpec;
+ TSDL_AudioSpec = record
+ freq: Integer; // DSP frequency -- samples per second
+ format: UInt16; // Audio data format
+ channels: UInt8; // Number of channels: 1 mono, 2 stereo
+ silence: UInt8; // Audio buffer silence value (calculated)
+ samples: UInt16; // Audio buffer size in samples
+ padding: UInt16; // Necessary for some compile environments
+ size: UInt32; // Audio buffer size in bytes (calculated)
+ { This function is called when the audio device needs more data.
+ 'stream' is a pointer to the audio data buffer
+ 'len' is the length of that buffer in bytes.
+ Once the callback returns, the buffer will no longer be valid.
+ Stereo samples are stored in a LRLRLR ordering.}
+ callback: TSDL_AudioSpecCallback;
+ userdata: Pointer;
+ end;
+
+ // A structure to hold a set of audio conversion filters and buffers
+ PSDL_AudioCVT = ^TSDL_AudioCVT;
+
+ PSDL_AudioCVTFilter = ^TSDL_AudioCVTFilter;
+ TSDL_AudioCVTFilter = record
+ cvt: PSDL_AudioCVT;
+ format: UInt16;
+ end;
+
+ PSDL_AudioCVTFilterArray = ^TSDL_AudioCVTFilterArray;
+ TSDL_AudioCVTFilterArray = array[0..9] of PSDL_AudioCVTFilter;
+
+ TSDL_AudioCVT = record
+ needed: Integer; // Set to 1 if conversion possible
+ src_format: UInt16; // Source audio format
+ dst_format: UInt16; // Target audio format
+ rate_incr: double; // Rate conversion increment
+ buf: PUInt8; // Buffer to hold entire audio data
+ len: Integer; // Length of original audio buffer
+ len_cvt: Integer; // Length of converted audio buffer
+ len_mult: Integer; // buffer must be len*len_mult big
+ len_ratio: double; // Given len, final size is len*len_ratio
+ filters: TSDL_AudioCVTFilterArray;
+ filter_index: Integer; // Current audio conversion function
+ end;
+
+ TSDL_Audiostatus = (
+ SDL_AUDIO_STOPPED,
+ SDL_AUDIO_PLAYING,
+ SDL_AUDIO_PAUSED
+ );
+
+ // SDL_cdrom.h types
+ TSDL_CDStatus = (
+ CD_ERROR,
+ CD_TRAYEMPTY,
+ CD_STOPPED,
+ CD_PLAYING,
+ CD_PAUSED );
+
+ PSDL_CDTrack = ^TSDL_CDTrack;
+ TSDL_CDTrack = record
+ id: UInt8; // Track number
+ type_: UInt8; // Data or audio track
+ unused: UInt16;
+ length: UInt32; // Length, in frames, of this track
+ offset: UInt32; // Offset, in frames, from start of disk
+ end;
+
+ // This structure is only current as of the last call to SDL_CDStatus()
+ PSDL_CD = ^TSDL_CD;
+ TSDL_CD = record
+ id: Integer; // Private drive identifier
+ status: TSDL_CDStatus; // Current drive status
+
+ // The rest of this structure is only valid if there's a CD in drive
+ numtracks: Integer; // Number of tracks on disk
+ cur_track: Integer; // Current track position
+ cur_frame: Integer; // Current frame offset within current track
+ track: array[0..SDL_MAX_TRACKS] of TSDL_CDTrack;
+ end;
+
+ //SDL_joystick.h types
+ PTransAxis = ^TTransAxis;
+ TTransAxis = record
+ offset: Integer;
+ scale: single;
+ end;
+
+ // The private structure used to keep track of a joystick
+ PJoystick_hwdata = ^TJoystick_hwdata;
+ TJoystick_hwdata = record
+ // joystick ID
+ id: Integer;
+ // values used to translate device-specific coordinates into SDL-standard ranges
+ transaxis: array[0..5] of TTransAxis;
+ end;
+
+ PBallDelta = ^TBallDelta;
+ TBallDelta = record
+ dx: Integer;
+ dy: Integer;
+ end; // Current ball motion deltas
+
+ // The SDL joystick structure
+ PSDL_Joystick = ^TSDL_Joystick;
+ TSDL_Joystick = record
+ index: UInt8; // Device index
+ name: PChar; // Joystick name - system dependent
+
+ naxes: Integer; // Number of axis controls on the joystick
+ axes: PUInt16; // Current axis states
+
+ nhats: Integer; // Number of hats on the joystick
+ hats: PUInt8; // Current hat states
+
+ nballs: Integer; // Number of trackballs on the joystick
+ balls: PBallDelta; // Current ball motion deltas
+
+ nbuttons: Integer; // Number of buttons on the joystick
+ buttons: PUInt8; // Current button states
+
+ hwdata: PJoystick_hwdata; // Driver dependent information
+
+ ref_count: Integer; // Reference count for multiple opens
+ end;
+
+ // SDL_verion.h types
+ PSDL_version = ^TSDL_version;
+ TSDL_version = record
+ major: UInt8;
+ minor: UInt8;
+ patch: UInt8;
+ end;
+
+ // SDL_keyboard.h types
+ TSDLKey = LongWord;
+
+ TSDLMod = LongWord;
+
+ PSDL_KeySym = ^TSDL_KeySym;
+ TSDL_KeySym = record
+ scancode: UInt8; // hardware specific scancode
+ sym: TSDLKey; // SDL virtual keysym
+ modifier: TSDLMod; // current key modifiers
+ unicode: UInt16; // translated character
+ end;
+
+ // SDL_events.h types
+ {Checks the event queue for messages and optionally returns them.
+ If 'action' is SDL_ADDEVENT, up to 'numevents' events will be added to
+ the back of the event queue.
+ If 'action' is SDL_PEEKEVENT, up to 'numevents' events at the front
+ of the event queue, matching 'mask', will be returned and will not
+ be removed from the queue.
+ If 'action' is SDL_GETEVENT, up to 'numevents' events at the front
+ of the event queue, matching 'mask', will be returned and will be
+ removed from the queue.
+ This function returns the number of events actually stored, or -1
+ if there was an error. This function is thread-safe. }
+
+ TSDL_EventAction = (SDL_ADDEVENT, SDL_PEEKEVENT, SDL_GETEVENT);
+
+ // Application visibility event structure
+ TSDL_ActiveEvent = record
+ type_: UInt8; // SDL_ACTIVEEVENT
+ gain: UInt8; // Whether given states were gained or lost (1/0)
+ state: UInt8; // A mask of the focus states
+ end;
+
+ // Keyboard event structure
+ TSDL_KeyboardEvent = record
+ type_: UInt8; // SDL_KEYDOWN or SDL_KEYUP
+ which: UInt8; // The keyboard device index
+ state: UInt8; // SDL_PRESSED or SDL_RELEASED
+ keysym: TSDL_KeySym;
+ end;
+
+ // Mouse motion event structure
+ TSDL_MouseMotionEvent = record
+ type_: UInt8; // SDL_MOUSEMOTION
+ which: UInt8; // The mouse device index
+ state: UInt8; // The current button state
+ x, y: UInt16; // The X/Y coordinates of the mouse
+ xrel: SInt16; // The relative motion in the X direction
+ yrel: SInt16; // The relative motion in the Y direction
+ end;
+
+ // Mouse button event structure
+ TSDL_MouseButtonEvent = record
+ type_: UInt8; // SDL_MOUSEBUTTONDOWN or SDL_MOUSEBUTTONUP
+ which: UInt8; // The mouse device index
+ button: UInt8; // The mouse button index
+ state: UInt8; // SDL_PRESSED or SDL_RELEASED
+ x: UInt16; // The X coordinates of the mouse at press time
+ y: UInt16; // The Y coordinates of the mouse at press time
+ end;
+
+ // Joystick axis motion event structure
+ TSDL_JoyAxisEvent = record
+ type_: UInt8; // SDL_JOYAXISMOTION
+ which: UInt8; // The joystick device index
+ axis: UInt8; // The joystick axis index
+ value: SInt16; // The axis value (range: -32768 to 32767)
+ end;
+
+ // Joystick trackball motion event structure
+ TSDL_JoyBallEvent = record
+ type_: UInt8; // SDL_JOYAVBALLMOTION
+ which: UInt8; // The joystick device index
+ ball: UInt8; // The joystick trackball index
+ xrel: SInt16; // The relative motion in the X direction
+ yrel: SInt16; // The relative motion in the Y direction
+ end;
+
+ // Joystick hat position change event structure
+ TSDL_JoyHatEvent = record
+ type_: UInt8; // SDL_JOYHATMOTION */
+ which: UInt8; // The joystick device index */
+ hat: UInt8; // The joystick hat index */
+ value: UInt8; { The hat position value:
+ 8 1 2
+ 7 0 3
+ 6 5 4
+
+ Note that zero means the POV is centered. }
+
+ end;
+
+ // Joystick button event structure
+ TSDL_JoyButtonEvent = record
+ type_: UInt8; // SDL_JOYBUTTONDOWN or SDL_JOYBUTTONUP
+ which: UInt8; // The joystick device index
+ button: UInt8; // The joystick button index
+ state: UInt8; // SDL_PRESSED or SDL_RELEASED
+ end;
+
+ { The "window resized" event
+ When you get this event, you are responsible for setting a new video
+ mode with the new width and height. }
+ TSDL_ResizeEvent = record
+ type_: UInt8; // SDL_VIDEORESIZE
+ w: Integer; // New width
+ h: Integer; // New height
+ end;
+
+ // The "quit requested" event
+ PSDL_QuitEvent = ^TSDL_QuitEvent;
+ TSDL_QuitEvent = record
+ type_: UInt8;
+ end;
+
+ // A user-defined event type
+ PSDL_UserEvent = ^TSDL_UserEvent;
+ TSDL_UserEvent = record
+ type_: UInt8; // SDL_USEREVENT through SDL_NUMEVENTS-1
+ code: Integer; // User defined event code */
+ data1: Pointer; // User defined data pointer */
+ data2: Pointer; // User defined data pointer */
+ end;
+
+ // The "screen redraw" event
+ PSDL_ExposeEvent = ^TSDL_ExposeEvent;
+ TSDL_ExposeEvent = record
+ type_ : Uint8; // SDL_VIDEOEXPOSE
+ end;
+
+ {$IFDEF Unix}
+ //These are the various supported subsystems under UNIX
+ TSDL_SysWm = ( SDL_SYSWM_X11 ) ;
+ {$ENDIF}
+
+// The windows custom event structure
+{$IFDEF WINDOWS}
+ PSDL_SysWMmsg = ^TSDL_SysWMmsg;
+ TSDL_SysWMmsg = record
+ version: TSDL_version;
+ h_wnd: HWND; // The window for the message
+ msg: UInt; // The type of message
+ w_Param: WPARAM; // WORD message parameter
+ lParam: LPARAM; // LONG message parameter
+ end;
+{$ELSE}
+
+{$IFDEF Unix}
+{ The Linux custom event structure }
+ PSDL_SysWMmsg = ^TSDL_SysWMmsg;
+ TSDL_SysWMmsg = record
+ version : TSDL_version;
+ subsystem : TSDL_SysWm;
+ {$IFDEF FPC}
+ {$IFNDEF GP2X}
+ event : TXEvent;
+ {$ENDIF}
+ {$ELSE}
+ event : XEvent;
+ {$ENDIF}
+ end;
+{$ELSE}
+{ The generic custom event structure }
+ PSDL_SysWMmsg = ^TSDL_SysWMmsg;
+ TSDL_SysWMmsg = record
+ version: TSDL_version;
+ data: Integer;
+ end;
+{$ENDIF}
+
+{$ENDIF}
+
+// The Windows custom window manager information structure
+{$IFDEF WINDOWS}
+ PSDL_SysWMinfo = ^TSDL_SysWMinfo;
+ TSDL_SysWMinfo = record
+ version : TSDL_version;
+ window : HWnd; // The display window
+ end;
+{$ELSE}
+
+// The Linux custom window manager information structure
+{$IFDEF Unix}
+ {$IFNDEF GP2X}
+ TX11 = record
+ display : PDisplay; // The X11 display
+ window : TWindow ; // The X11 display window */
+ {* These locking functions should be called around
+ any X11 functions using the display variable.
+ They lock the event thread, so should not be
+ called around event functions or from event filters.
+ *}
+ lock_func : Pointer;
+ unlock_func : Pointer;
+
+ // Introduced in SDL 1.0.2
+ fswindow : TWindow ; // The X11 fullscreen window */
+ wmwindow : TWindow ; // The X11 managed input window */
+ end;
+ {$ENDIF}
+
+ PSDL_SysWMinfo = ^TSDL_SysWMinfo;
+ TSDL_SysWMinfo = record
+ version : TSDL_version ;
+ subsystem : TSDL_SysWm;
+ {$IFNDEF GP2X}
+ X11 : TX11;
+ {$ENDIF}
+ end;
+{$ELSE}
+ // The generic custom window manager information structure
+ PSDL_SysWMinfo = ^TSDL_SysWMinfo;
+ TSDL_SysWMinfo = record
+ version : TSDL_version ;
+ data : integer;
+ end;
+{$ENDIF}
+
+{$ENDIF}
+
+ PSDL_SysWMEvent = ^TSDL_SysWMEvent;
+ TSDL_SysWMEvent = record
+ type_: UInt8;
+ msg: PSDL_SysWMmsg;
+ end;
+
+ PSDL_Event = ^TSDL_Event;
+ TSDL_Event = record
+ case UInt8 of
+ SDL_NOEVENT: (type_: byte);
+ SDL_ACTIVEEVENT: (active: TSDL_ActiveEvent);
+ SDL_KEYDOWN, SDL_KEYUP: (key: TSDL_KeyboardEvent);
+ SDL_MOUSEMOTION: (motion: TSDL_MouseMotionEvent);
+ SDL_MOUSEBUTTONDOWN, SDL_MOUSEBUTTONUP: (button: TSDL_MouseButtonEvent );
+ SDL_JOYAXISMOTION: (jaxis: TSDL_JoyAxisEvent );
+ SDL_JOYBALLMOTION: (jball: TSDL_JoyBallEvent );
+ SDL_JOYHATMOTION: (jhat: TSDL_JoyHatEvent );
+ SDL_JOYBUTTONDOWN, SDL_JOYBUTTONUP: (jbutton: TSDL_JoyButtonEvent );
+ SDL_VIDEORESIZE: (resize: TSDL_ResizeEvent );
+ SDL_QUITEV: (quit: TSDL_QuitEvent );
+ SDL_USEREVENT : ( user : TSDL_UserEvent );
+ SDL_SYSWMEVENT: (syswm: TSDL_SysWMEvent );
+ end;
+
+
+{ This function sets up a filter to process all events before they
+ change internal state and are posted to the internal event queue.
+
+ The filter is protypted as: }
+ {$IFNDEF __GPC__}
+ TSDL_EventFilter = function( event : PSDL_Event ): Integer; cdecl;
+ {$ELSE}
+ TSDL_EventFilter = function( event : PSDL_Event ): Integer;
+ {$ENDIF}
+
+ // SDL_video.h types
+ // Useful data types
+ PPSDL_Rect = ^PSDL_Rect;
+ PSDL_Rect = ^TSDL_Rect;
+ TSDL_Rect = record
+ x, y: SInt16;
+ w, h: UInt16;
+ end;
+
+ SDL_Rect = TSDL_Rect;
+{$EXTERNALSYM SDL_Rect}
+
+ PSDL_Color = ^TSDL_Color;
+ TSDL_Color = record
+ r: UInt8;
+ g: UInt8;
+ b: UInt8;
+ unused: UInt8;
+ end;
+
+ PSDL_ColorArray = ^TSDL_ColorArray;
+ TSDL_ColorArray = array[0..65000] of TSDL_Color;
+
+ PSDL_Palette = ^TSDL_Palette;
+ TSDL_Palette = record
+ ncolors: Integer;
+ colors: PSDL_ColorArray;
+ end;
+
+ // Everything in the pixel format structure is read-only
+ PSDL_PixelFormat = ^TSDL_PixelFormat;
+ TSDL_PixelFormat = record
+ palette: PSDL_Palette;
+ BitsPerPixel: UInt8;
+ BytesPerPixel: UInt8;
+ Rloss: UInt8;
+ Gloss: UInt8;
+ Bloss: UInt8;
+ Aloss: UInt8;
+ Rshift: UInt8;
+ Gshift: UInt8;
+ Bshift: UInt8;
+ Ashift: UInt8;
+ RMask: UInt32;
+ GMask: UInt32;
+ BMask: UInt32;
+ AMask: UInt32;
+ colorkey: UInt32; // RGB color key information
+ alpha: UInt8; // Alpha value information (per-surface alpha)
+ end;
+
+{$IFDEF WINDOWS}
+ {PPrivate_hwdata = ^TPrivate_hwdata;
+ TPrivate_hwdata = record
+ dd_surface : IDIRECTDRAWSURFACE3;
+ dd_writebuf : IDIRECTDRAWSURFACE3;
+ end;}
+ {ELSE}
+{$ENDIF}
+
+ // The structure passed to the low level blit functions
+ PSDL_BlitInfo = ^TSDL_BlitInfo;
+ TSDL_BlitInfo = record
+ s_pixels: PUInt8;
+ s_width: Integer;
+ s_height: Integer;
+ s_skip: Integer;
+ d_pixels: PUInt8;
+ d_width: Integer;
+ d_height: Integer;
+ d_skip: Integer;
+ aux_data: Pointer;
+ src: PSDL_PixelFormat;
+ table: PUInt8;
+ dst: PSDL_PixelFormat;
+ end;
+
+ // typedef for private surface blitting functions
+ PSDL_Surface = ^TSDL_Surface;
+
+ {$IFNDEF __GPC__}
+ TSDL_Blit = function( src: PSDL_Surface; srcrect: PSDL_Rect; dst: PSDL_Surface; dstrect: PSDL_Rect ): Integer; cdecl;
+ {$ELSE}
+ TSDL_Blit = function( src: PSDL_Surface; srcrect: PSDL_Rect; dst: PSDL_Surface; dstrect: PSDL_Rect ): Integer;
+ {$ENDIF}
+
+ // The type definition for the low level blit functions
+ //TSDL_LoBlit = procedure( info : PSDL_BlitInfo ); cdecl;
+
+ // This is the private info structure for software accelerated blits
+ {PPrivate_swaccel = ^TPrivate_swaccel;
+ TPrivate_swaccel = record
+ blit : TSDL_LoBlit;
+ aux_data : Pointer;
+ end;}
+
+ // Blit mapping definition
+ {PSDL_BlitMap = ^TSDL_BlitMap;
+ TSDL_BlitMap = record
+ dst : PSDL_Surface;
+ identity : Integer;
+ table : PUInt8;
+ hw_blit : TSDL_Blit;
+ sw_blit : TSDL_Blit;
+ hw_data : PPrivate_hwaccel;
+ sw_data : PPrivate_swaccel;
+
+ // the version count matches the destination; mismatch indicates an invalid mapping
+ format_version : Cardinal;
+ end;}
+
+ TSDL_Surface = record
+ flags: UInt32; // Read-only
+ format: PSDL_PixelFormat; // Read-only
+ w, h: Integer; // Read-only
+ pitch: UInt16; // Read-only
+ pixels: Pointer; // Read-write
+ offset: Integer; // Private
+ hwdata: Pointer; //TPrivate_hwdata; Hardware-specific surface info
+
+ // clipping information:
+ clip_rect: TSDL_Rect; // Read-only
+ unused1: UInt32; // for binary compatibility
+ // Allow recursive locks
+ locked: UInt32; // Private
+ // info for fast blit mapping to other surfaces
+ Blitmap: Pointer; // PSDL_BlitMap; // Private
+ // format version, bumped at every change to invalidate blit maps
+ format_version: Cardinal; // Private
+ refcount: Integer;
+ end;
+
+ // Useful for determining the video hardware capabilities
+ PSDL_VideoInfo = ^TSDL_VideoInfo;
+ TSDL_VideoInfo = record
+ hw_available: UInt8; // Hardware and WindowManager flags in first 2 bits ( see below )
+ {hw_available: 1; // Can you create hardware surfaces
+ wm_available: 1; // Can you talk to a window manager?
+ UnusedBits1: 6;}
+ blit_hw: UInt8; // Blit Hardware flags. See below for which bits do what
+ {UnusedBits2: 1;
+ blit_hw: 1; // Flag:UInt32 Accelerated blits HW --> HW
+ blit_hw_CC: 1; // Flag:UInt32 Accelerated blits with Colorkey
+ blit_hw_A: 1; // Flag:UInt32 Accelerated blits with Alpha
+ blit_sw: 1; // Flag:UInt32 Accelerated blits SW --> HW
+ blit_sw_CC: 1; // Flag:UInt32 Accelerated blits with Colorkey
+ blit_sw_A: 1; // Flag:UInt32 Accelerated blits with Alpha
+ blit_fill: 1; // Flag:UInt32 Accelerated color fill}
+ UnusedBits3: UInt8; // Unused at this point
+ video_mem: UInt32; // The total amount of video memory (in K)
+ vfmt: PSDL_PixelFormat; // Value: The format of the video surface
+ current_w : SInt32; // Value: The current video mode width
+ current_h : SInt32; // Value: The current video mode height
+ end;
+
+ // The YUV hardware video overlay
+ PSDL_Overlay = ^TSDL_Overlay;
+ TSDL_Overlay = record
+ format: UInt32; // Overlay format
+ w, h: Integer; // Width and height of overlay
+ planes: Integer; // Number of planes in the overlay. Usually either 1 or 3
+ pitches: PUInt16;
+ // An array of pitches, one for each plane. Pitch is the length of a row in bytes.
+ pixels: PPUInt8;
+ // An array of pointers to the data of each plane. The overlay should be locked before these pointers are used.
+ hw_overlay: UInt32;
+ // This will be set to 1 if the overlay is hardware accelerated.
+ end;
+
+ // Public enumeration for setting the OpenGL window attributes.
+ TSDL_GLAttr = (
+ SDL_GL_RED_SIZE,
+ SDL_GL_GREEN_SIZE,
+ SDL_GL_BLUE_SIZE,
+ SDL_GL_ALPHA_SIZE,
+ SDL_GL_BUFFER_SIZE,
+ SDL_GL_DOUBLEBUFFER,
+ SDL_GL_DEPTH_SIZE,
+ SDL_GL_STENCIL_SIZE,
+ SDL_GL_ACCUM_RED_SIZE,
+ SDL_GL_ACCUM_GREEN_SIZE,
+ SDL_GL_ACCUM_BLUE_SIZE,
+ SDL_GL_ACCUM_ALPHA_SIZE,
+ SDL_GL_STEREO,
+ SDL_GL_MULTISAMPLEBUFFERS,
+ SDL_GL_MULTISAMPLESAMPLES,
+ SDL_GL_ACCELERATED_VISUAL,
+ SDL_GL_SWAP_CONTROL);
+
+
+
+ PSDL_Cursor = ^TSDL_Cursor;
+ TSDL_Cursor = record
+ area: TSDL_Rect; // The area of the mouse cursor
+ hot_x, hot_y: SInt16; // The "tip" of the cursor
+ data: PUInt8; // B/W cursor data
+ mask: PUInt8; // B/W cursor mask
+ save: array[1..2] of PUInt8; // Place to save cursor area
+ wm_cursor: Pointer; // Window-manager cursor
+ end;
+
+// SDL_mutex.h types
+
+{$IFDEF WINDOWS}
+ PSDL_Mutex = ^TSDL_Mutex;
+ TSDL_Mutex = record
+ id: THANDLE;
+ end;
+{$ENDIF}
+
+{$IFDEF Unix}
+ PSDL_Mutex = ^TSDL_Mutex;
+ TSDL_mutex = record
+ id: pthread_mutex_t;
+{$IFDEF PTHREAD_NO_RECURSIVE_MUTEX}
+ recursive: Integer;
+ owner: pthread_t;
+{$ENDIF}
+ end;
+{$ENDIF}
+
+{$IFDEF NDS}
+ PSDL_mutex = ^TSDL_Mutex;
+ TSDL_Mutex = record
+ recursive: Integer;
+ Owner: UInt32;
+ sem: PSDL_sem;
+ end;
+{$ENDIF}
+
+{$IFDEF MORPHOS}
+ PSDL_Mutex = ^TSDL_Mutex;
+ TSDL_Mutex = record
+{$WARNING FIXME!!}
+ dummy: longint;
+ end;
+{$ENDIF}
+
+{$IFDEF __MACH__}
+ {$define USE_NAMED_SEMAPHORES}
+ // Broken sem_getvalue() in MacOS X Public Beta */
+ {$define BROKEN_SEMGETVALUE}
+{$ENDIF}
+
+PSDL_semaphore = ^TSDL_semaphore;
+{$IFDEF WINDOWS}
+ // WINDOWS or Machintosh
+ TSDL_semaphore = record
+ id: THANDLE;
+ count: UInt32;
+ end;
+{$ELSE}
+ {$IFDEF FPC}
+ // This should be semaphore.h
+ __sem_lock_t = {packed} record { Not in header file - anonymous }
+ status: Longint;
+ spinlock: Integer;
+ end;
+
+ sem_t = {packed} record
+ __sem_lock: __sem_lock_t;
+ __sem_value: Integer;
+ __sem_waiting: longint ; {_pthread_queue;}
+ end;
+ {$ENDIF}
+
+ TSDL_semaphore = record
+ sem: Pointer; //PSem_t;
+ {$IFNDEF USE_NAMED_SEMAPHORES}
+ sem_data: Sem_t;
+ {$ENDIF}
+
+ {$IFDEF BROKEN_SEMGETVALUE}
+ { This is a little hack for MacOS X -
+ It's not thread-safe, but it's better than nothing }
+ sem_value: Integer;
+ {$ENDIF}
+ end;
+{$ENDIF}
+
+ PSDL_Sem = ^TSDL_Sem;
+ TSDL_Sem = TSDL_Semaphore;
+
+ PSDL_Cond = ^TSDL_Cond;
+ TSDL_Cond = record
+{$IFDEF Unix}
+ cond: pthread_cond_t;
+{$ELSE}
+ // Generic Cond structure
+ lock: PSDL_mutex;
+ waiting: Integer;
+ signals: Integer;
+ wait_sem: PSDL_Sem;
+ wait_done: PSDL_Sem;
+{$ENDIF}
+ end;
+
+ // SDL_thread.h types
+{$IFDEF WINDOWS}
+ TSYS_ThreadHandle = THandle;
+{$ENDIF}
+
+{$IFDEF Unix}
+ TSYS_ThreadHandle = pthread_t;
+{$ENDIF}
+
+{$IFDEF NDS}
+ TSYS_ThreadHandle = Integer;
+{$ENDIF}
+
+{$IFDEF MORPHOS}
+ TSYS_ThreadHandle = Pointer;
+{$ENDIF}
+
+ { This is the system-independent thread info structure }
+ PSDL_Thread = ^TSDL_Thread;
+ TSDL_Thread = record
+ threadid: UInt32;
+ handle: TSYS_ThreadHandle;
+ status: Integer;
+ errbuf: TSDL_Error;
+ data: Pointer;
+ end;
+
+ // Helper Types
+
+ // Keyboard State Array ( See demos for how to use )
+ PKeyStateArr = ^TKeyStateArr;
+ TKeyStateArr = array[0..65000] of UInt8;
+
+ // Types required so we don't need to use Windows.pas
+ PInteger = ^Integer;
+ PByte = ^Byte;
+ PWord = ^Word;
+ PLongWord = ^Longword;
+
+ // General arrays
+ PByteArray = ^TByteArray;
+ TByteArray = array[0..32767] of Byte;
+
+ PWordArray = ^TWordArray;
+ TWordArray = array[0..16383] of Word;
+
+ PPoint = ^TPoint;
+ {$IFDEF HAS_TYPES}
+ TPoint = Types.TPoint;
+ {$ELSE}
+ {$IFDEF WINDOWS}
+ {$IFDEF __GPC__}
+ TPoint = wintypes.TPoint;
+ {$ELSE}
+ TPoint = Windows.TPoint;
+ {$ENDIF}
+ {$ELSE}
+ //Can't define TPoint : neither Types nor Windows unit available.
+ {$ENDIF}
+ {$ENDIF}
+
+ PRect = ^TRect;
+ {$IFDEF HAS_TYPES}
+ TRect = Types.TRect;
+ {$ELSE}
+ {$IFDEF WINDOWS}
+ {$IFDEF __GPC__}
+ TRect = wintypes.TRect;
+ {$ELSE}
+ TRect = Windows.TRect;
+ {$ENDIF}
+ {$ELSE}
+ //Can't define TRect: neither Types nor Windows unit available.
+ {$ENDIF}
+ {$ENDIF}
+
+ { Generic procedure pointer }
+ TProcedure = procedure;
+
+{------------------------------------------------------------------------------}
+{ initialization }
+{------------------------------------------------------------------------------}
+
+{ This function loads the SDL dynamically linked library and initializes
+ the subsystems specified by 'flags' (and those satisfying dependencies)
+ Unless the SDL_INIT_NOPARACHUTE flag is set, it will install cleanup
+ signal handlers for some commonly ignored fatal signals (like SIGSEGV) }
+
+{$IFDEF MORPHOS}
+{$I powersdl.inc}
+{$ELSE}
+function SDL_Init( flags : UInt32 ) : Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_Init'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_Init}
+
+// This function initializes specific SDL subsystems
+function SDL_InitSubSystem( flags : UInt32 ) : Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_InitSubSystem'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_InitSubSystem}
+
+// This function cleans up specific SDL subsystems
+procedure SDL_QuitSubSystem( flags : UInt32 );
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_QuitSubSystem'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_QuitSubSystem}
+
+{ This function returns mask of the specified subsystems which have
+ been initialized.
+ If 'flags' is 0, it returns a mask of all initialized subsystems. }
+
+function SDL_WasInit( flags : UInt32 ): UInt32;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_WasInit'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_WasInit}
+
+{ This function cleans up all initialized subsystems and unloads the
+ dynamically linked library. You should call it upon all exit conditions. }
+procedure SDL_Quit;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_Quit'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_Quit}
+
+{$IFDEF WINDOWS}
+// This should be called from your WinMain() function, if any
+function SDL_RegisterApp(name: PChar; style: UInt32; h_Inst: Pointer): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_RegisterApp'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_RegisterApp}
+{$ENDIF}
+
+{$IFDEF __MACH__}
+// This should be called from your main() function, if any
+procedure SDL_InitQuickDraw( the_qd: QDGlobals );
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_InitQuickDraw'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_InitQuickDraw}
+{$ENDIF}
+
+
+{------------------------------------------------------------------------------}
+{ types }
+{------------------------------------------------------------------------------}
+// The number of elements in a table
+function SDL_TableSize( table: PChar ): Integer;
+{$EXTERNALSYM SDL_TABLESIZE}
+
+
+{------------------------------------------------------------------------------}
+{ error-handling }
+{------------------------------------------------------------------------------}
+// Public functions
+function SDL_GetError: PChar;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_GetError'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_GetError}
+procedure SDL_SetError(fmt: PChar);
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_SetError'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_SetError}
+procedure SDL_ClearError;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_ClearError'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_ClearError}
+
+{$IFNDEF WINDOWS}
+procedure SDL_Error(Code: TSDL_errorcode);
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_Error'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_Error}
+{$ENDIF}
+
+// Private error message function - used internally
+procedure SDL_OutOfMemory;
+
+{------------------------------------------------------------------------------}
+{ io handling }
+{------------------------------------------------------------------------------}
+// Functions to create SDL_RWops structures from various data sources
+
+function SDL_RWFromFile(filename, mode: PChar): PSDL_RWops;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_RWFromFile'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_RWFromFile}
+procedure SDL_FreeRW(area: PSDL_RWops);
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_FreeRW'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_FreeRW}
+
+//fp is FILE *fp ???
+function SDL_RWFromFP(fp: Pointer; autoclose: Integer): PSDL_RWops;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_RWFromFP'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_RWFromFP}
+function SDL_RWFromMem(mem: Pointer; size: Integer): PSDL_RWops;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_RWFromMem'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_RWFromMem}
+function SDL_RWFromConstMem(const mem: Pointer; size: Integer) : PSDL_RWops;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_RWFromConstMem'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_RWFromConstMem}
+function SDL_AllocRW: PSDL_RWops;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_AllocRW'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_AllocRW}
+
+function SDL_RWSeek(context: PSDL_RWops; offset: Integer; whence: Integer) : Integer;
+{$EXTERNALSYM SDL_RWSeek}
+function SDL_RWTell(context: PSDL_RWops): Integer;
+{$EXTERNALSYM SDL_RWTell}
+function SDL_RWRead(context: PSDL_RWops; ptr: Pointer; size: Integer; n : Integer): Integer;
+{$EXTERNALSYM SDL_RWRead}
+function SDL_RWWrite(context: PSDL_RWops; ptr: Pointer; size: Integer; n : Integer): Integer;
+{$EXTERNALSYM SDL_RWWrite}
+function SDL_RWClose(context: PSDL_RWops): Integer;
+{$EXTERNALSYM SDL_RWClose}
+
+{------------------------------------------------------------------------------}
+{ time-handling }
+{------------------------------------------------------------------------------}
+
+{ Get the number of milliseconds since the SDL library initialization. }
+{ Note that this value wraps if the program runs for more than ~49 days. }
+function SDL_GetTicks: UInt32;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_GetTicks'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_GetTicks}
+
+// Wait a specified number of milliseconds before returning
+procedure SDL_Delay(msec: UInt32);
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_Delay'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_Delay}
+
+{ Add a new timer to the pool of timers already running. }
+{ Returns a timer ID, or NULL when an error occurs. }
+function SDL_AddTimer(interval: UInt32; callback: TSDL_NewTimerCallback; param : Pointer): PSDL_TimerID;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_AddTimer'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_AddTimer}
+
+{ Remove one of the multiple timers knowing its ID. }
+{ Returns a boolean value indicating success. }
+function SDL_RemoveTimer(t: PSDL_TimerID): TSDL_Bool;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_RemoveTimer'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_RemoveTimer}
+
+function SDL_SetTimer(interval: UInt32; callback: TSDL_TimerCallback): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_SetTimer'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_SetTimer}
+
+{------------------------------------------------------------------------------}
+{ audio-routines }
+{------------------------------------------------------------------------------}
+
+{ These functions are used internally, and should not be used unless you
+ have a specific need to specify the audio driver you want to use.
+ You should normally use SDL_Init() or SDL_InitSubSystem(). }
+
+function SDL_AudioInit(driver_name: PChar): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_AudioInit'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_AudioInit}
+procedure SDL_AudioQuit;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_AudioQuit'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_AudioQuit}
+
+{ This function fills the given character buffer with the name of the
+ current audio driver, and returns a Pointer to it if the audio driver has
+ been initialized. It returns NULL if no driver has been initialized. }
+
+function SDL_AudioDriverName(namebuf: PChar; maxlen: Integer): PChar;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_AudioDriverName'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_AudioDriverName}
+
+{ This function opens the audio device with the desired parameters, and
+ returns 0 if successful, placing the actual hardware parameters in the
+ structure pointed to by 'obtained'. If 'obtained' is NULL, the audio
+ data passed to the callback function will be guaranteed to be in the
+ requested format, and will be automatically converted to the hardware
+ audio format if necessary. This function returns -1 if it failed
+ to open the audio device, or couldn't set up the audio thread.
+
+ When filling in the desired audio spec structure,
+ 'desired->freq' should be the desired audio frequency in samples-per-second.
+ 'desired->format' should be the desired audio format.
+ 'desired->samples' is the desired size of the audio buffer, in samples.
+ This number should be a power of two, and may be adjusted by the audio
+ driver to a value more suitable for the hardware. Good values seem to
+ range between 512 and 8096 inclusive, depending on the application and
+ CPU speed. Smaller values yield faster response time, but can lead
+ to underflow if the application is doing heavy processing and cannot
+ fill the audio buffer in time. A stereo sample consists of both right
+ and left channels in LR ordering.
+ Note that the number of samples is directly related to time by the
+ following formula: ms = (samples*1000)/freq
+ 'desired->size' is the size in bytes of the audio buffer, and is
+ calculated by SDL_OpenAudio().
+ 'desired->silence' is the value used to set the buffer to silence,
+ and is calculated by SDL_OpenAudio().
+ 'desired->callback' should be set to a function that will be called
+ when the audio device is ready for more data. It is passed a pointer
+ to the audio buffer, and the length in bytes of the audio buffer.
+ This function usually runs in a separate thread, and so you should
+ protect data structures that it accesses by calling SDL_LockAudio()
+ and SDL_UnlockAudio() in your code.
+ 'desired->userdata' is passed as the first parameter to your callback
+ function.
+
+ The audio device starts out playing silence when it's opened, and should
+ be enabled for playing by calling SDL_PauseAudio(0) when you are ready
+ for your audio callback function to be called. Since the audio driver
+ may modify the requested size of the audio buffer, you should allocate
+ any local mixing buffers after you open the audio device. }
+
+function SDL_OpenAudio(desired, obtained: PSDL_AudioSpec): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_OpenAudio'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_OpenAudio}
+
+{ Get the current audio state: }
+function SDL_GetAudioStatus: TSDL_Audiostatus;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_GetAudioStatus'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_GetAudioStatus}
+
+{ This function pauses and unpauses the audio callback processing.
+ It should be called with a parameter of 0 after opening the audio
+ device to start playing sound. This is so you can safely initialize
+ data for your callback function after opening the audio device.
+ Silence will be written to the audio device during the pause. }
+
+procedure SDL_PauseAudio(pause_on: Integer);
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_PauseAudio'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_PauseAudio}
+
+{ This function loads a WAVE from the data source, automatically freeing
+ that source if 'freesrc' is non-zero. For example, to load a WAVE file,
+ you could do:
+ SDL_LoadWAV_RW(SDL_RWFromFile("sample.wav", "rb"), 1, ...);
+
+ If this function succeeds, it returns the given SDL_AudioSpec,
+ filled with the audio data format of the wave data, and sets
+ 'audio_buf' to a malloc()'d buffer containing the audio data,
+ and sets 'audio_len' to the length of that audio buffer, in bytes.
+ You need to free the audio buffer with SDL_FreeWAV() when you are
+ done with it.
+
+ This function returns NULL and sets the SDL error message if the
+ wave file cannot be opened, uses an unknown data format, or is
+ corrupt. Currently raw and MS-ADPCM WAVE files are supported. }
+
+function SDL_LoadWAV_RW(src: PSDL_RWops; freesrc: Integer; spec:
+ PSDL_AudioSpec; audio_buf: PUInt8; audiolen: PUInt32): PSDL_AudioSpec;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_LoadWAV_RW'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_LoadWAV_RW}
+
+// Compatibility convenience function -- loads a WAV from a file
+function SDL_LoadWAV(filename: PChar; spec: PSDL_AudioSpec; audio_buf:
+ PUInt8; audiolen: PUInt32): PSDL_AudioSpec;
+{$EXTERNALSYM SDL_LoadWAV}
+
+{ This function frees data previously allocated with SDL_LoadWAV_RW() }
+
+procedure SDL_FreeWAV(audio_buf: PUInt8);
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_FreeWAV'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_FreeWAV}
+
+{ This function takes a source format and rate and a destination format
+ and rate, and initializes the 'cvt' structure with information needed
+ by SDL_ConvertAudio() to convert a buffer of audio data from one format
+ to the other.
+ This function returns 0, or -1 if there was an error. }
+function SDL_BuildAudioCVT(cvt: PSDL_AudioCVT; src_format: UInt16;
+ src_channels: UInt8; src_rate: Integer; dst_format: UInt16; dst_channels: UInt8;
+ dst_rate: Integer): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_BuildAudioCVT'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_BuildAudioCVT}
+
+{ Once you have initialized the 'cvt' structure using SDL_BuildAudioCVT(),
+ created an audio buffer cvt->buf, and filled it with cvt->len bytes of
+ audio data in the source format, this function will convert it in-place
+ to the desired format.
+ The data conversion may expand the size of the audio data, so the buffer
+ cvt->buf should be allocated after the cvt structure is initialized by
+ SDL_BuildAudioCVT(), and should be cvt->len*cvt->len_mult bytes long. }
+function SDL_ConvertAudio(cvt: PSDL_AudioCVT): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_ConvertAudio'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_ConvertAudio}
+
+{ This takes two audio buffers of the playing audio format and mixes
+ them, performing addition, volume adjustment, and overflow clipping.
+ The volume ranges from 0 - 128, and should be set to SDL_MIX_MAXVOLUME
+ for full audio volume. Note this does not change hardware volume.
+ This is provided for convenience -- you can mix your own audio data. }
+
+procedure SDL_MixAudio(dst, src: PUInt8; len: UInt32; volume: Integer);
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_MixAudio'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_MixAudio}
+
+{ The lock manipulated by these functions protects the callback function.
+ During a LockAudio/UnlockAudio pair, you can be guaranteed that the
+ callback function is not running. Do not call these from the callback
+ function or you will cause deadlock. }
+procedure SDL_LockAudio;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_LockAudio'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_LockAudio}
+procedure SDL_UnlockAudio;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_UnlockAudio'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_UnlockAudio}
+
+{ This function shuts down audio processing and closes the audio device. }
+
+procedure SDL_CloseAudio;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_CloseAudio'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_CloseAudio}
+
+{------------------------------------------------------------------------------}
+{ CD-routines }
+{------------------------------------------------------------------------------}
+
+{ Returns the number of CD-ROM drives on the system, or -1 if
+ SDL_Init() has not been called with the SDL_INIT_CDROM flag. }
+
+function SDL_CDNumDrives: Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_CDNumDrives'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_CDNumDrives}
+
+{ Returns a human-readable, system-dependent identifier for the CD-ROM.
+ Example:
+ "/dev/cdrom"
+ "E:"
+ "/dev/disk/ide/1/master" }
+
+function SDL_CDName(drive: Integer): PChar;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_CDName'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_CDName}
+
+{ Opens a CD-ROM drive for access. It returns a drive handle on success,
+ or NULL if the drive was invalid or busy. This newly opened CD-ROM
+ becomes the default CD used when other CD functions are passed a NULL
+ CD-ROM handle.
+ Drives are numbered starting with 0. Drive 0 is the system default CD-ROM. }
+
+function SDL_CDOpen(drive: Integer): PSDL_CD;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_CDOpen'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_CDOpen}
+
+{ This function returns the current status of the given drive.
+ If the drive has a CD in it, the table of contents of the CD and current
+ play position of the CD will be stored in the SDL_CD structure. }
+
+function SDL_CDStatus(cdrom: PSDL_CD): TSDL_CDStatus;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_CDStatus'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_CDStatus}
+
+{ Play the given CD starting at 'start_track' and 'start_frame' for 'ntracks'
+ tracks and 'nframes' frames. If both 'ntrack' and 'nframe' are 0, play
+ until the end of the CD. This function will skip data tracks.
+ This function should only be called after calling SDL_CDStatus() to
+ get track information about the CD.
+
+ For example:
+ // Play entire CD:
+ if ( CD_INDRIVE(SDL_CDStatus(cdrom)) ) then
+ SDL_CDPlayTracks(cdrom, 0, 0, 0, 0);
+ // Play last track:
+ if ( CD_INDRIVE(SDL_CDStatus(cdrom)) ) then
+ begin
+ SDL_CDPlayTracks(cdrom, cdrom->numtracks-1, 0, 0, 0);
+ end;
+
+ // Play first and second track and 10 seconds of third track:
+ if ( CD_INDRIVE(SDL_CDStatus(cdrom)) )
+ SDL_CDPlayTracks(cdrom, 0, 0, 2, 10);
+
+ This function returns 0, or -1 if there was an error. }
+
+function SDL_CDPlayTracks(cdrom: PSDL_CD; start_track: Integer; start_frame:
+ Integer; ntracks: Integer; nframes: Integer): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_CDPlayTracks'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_CDPlayTracks}
+
+
+{ Play the given CD starting at 'start' frame for 'length' frames.
+ It returns 0, or -1 if there was an error. }
+
+function SDL_CDPlay(cdrom: PSDL_CD; start: Integer; length: Integer): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_CDPlay'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_CDPlay}
+
+// Pause play -- returns 0, or -1 on error
+function SDL_CDPause(cdrom: PSDL_CD): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_CDPause'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_CDPause}
+
+// Resume play -- returns 0, or -1 on error
+function SDL_CDResume(cdrom: PSDL_CD): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_CDResume'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_CDResume}
+
+// Stop play -- returns 0, or -1 on error
+function SDL_CDStop(cdrom: PSDL_CD): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_CDStop'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_CDStop}
+
+// Eject CD-ROM -- returns 0, or -1 on error
+function SDL_CDEject(cdrom: PSDL_CD): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_CDEject'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_CDEject}
+
+// Closes the handle for the CD-ROM drive
+procedure SDL_CDClose(cdrom: PSDL_CD);
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_CDClose'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_CDClose}
+
+// Given a status, returns true if there's a disk in the drive
+function SDL_CDInDrive( status : TSDL_CDStatus ) : LongBool;
+{$EXTERNALSYM SDL_CDInDrive}
+
+// Conversion functions from frames to Minute/Second/Frames and vice versa
+procedure FRAMES_TO_MSF(frames: Integer; var M: Integer; var S: Integer; var
+ F: Integer);
+{$EXTERNALSYM FRAMES_TO_MSF}
+function MSF_TO_FRAMES(M: Integer; S: Integer; F: Integer): Integer;
+{$EXTERNALSYM MSF_TO_FRAMES}
+
+{------------------------------------------------------------------------------}
+{ JoyStick-routines }
+{------------------------------------------------------------------------------}
+
+{ Count the number of joysticks attached to the system }
+function SDL_NumJoysticks: Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_NumJoysticks'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_NumJoysticks}
+
+{ Get the implementation dependent name of a joystick.
+ This can be called before any joysticks are opened.
+ If no name can be found, this function returns NULL. }
+function SDL_JoystickName(index: Integer): PChar;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_JoystickName'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_JoystickName}
+
+{ Open a joystick for use - the index passed as an argument refers to
+ the N'th joystick on the system. This index is the value which will
+ identify this joystick in future joystick events.
+
+ This function returns a joystick identifier, or NULL if an error occurred. }
+function SDL_JoystickOpen(index: Integer): PSDL_Joystick;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_JoystickOpen'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_JoystickOpen}
+
+{ Returns 1 if the joystick has been opened, or 0 if it has not. }
+function SDL_JoystickOpened(index: Integer): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_JoystickOpened'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_JoystickOpened}
+
+{ Get the device index of an opened joystick. }
+function SDL_JoystickIndex(joystick: PSDL_Joystick): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_JoystickIndex'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_JoystickIndex}
+
+{ Get the number of general axis controls on a joystick }
+function SDL_JoystickNumAxes(joystick: PSDL_Joystick): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_JoystickNumAxes'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_JoystickNumAxes}
+
+{ Get the number of trackballs on a joystick
+ Joystick trackballs have only relative motion events associated
+ with them and their state cannot be polled. }
+function SDL_JoystickNumBalls(joystick: PSDL_Joystick): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_JoystickNumBalls'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_JoystickNumBalls}
+
+
+{ Get the number of POV hats on a joystick }
+function SDL_JoystickNumHats(joystick: PSDL_Joystick): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_JoystickNumHats'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_JoystickNumHats}
+
+{ Get the number of buttons on a joystick }
+function SDL_JoystickNumButtons(joystick: PSDL_Joystick): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_JoystickNumButtons'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_JoystickNumButtons}
+
+{ Update the current state of the open joysticks.
+ This is called automatically by the event loop if any joystick
+ events are enabled. }
+
+procedure SDL_JoystickUpdate;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_JoystickUpdate'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_JoystickUpdate;}
+
+{ Enable/disable joystick event polling.
+ If joystick events are disabled, you must call SDL_JoystickUpdate()
+ yourself and check the state of the joystick when you want joystick
+ information.
+ The state can be one of SDL_QUERY, SDL_ENABLE or SDL_IGNORE. }
+
+function SDL_JoystickEventState(state: Integer): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_JoystickEventState'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_JoystickEventState}
+
+{ Get the current state of an axis control on a joystick
+ The state is a value ranging from -32768 to 32767.
+ The axis indices start at index 0. }
+
+function SDL_JoystickGetAxis(joystick: PSDL_Joystick; axis: Integer) : SInt16;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_JoystickGetAxis'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_JoystickGetAxis}
+
+{ The hat indices start at index 0. }
+
+function SDL_JoystickGetHat(joystick: PSDL_Joystick; hat: Integer): UInt8;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_JoystickGetHat'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_JoystickGetHat}
+
+{ Get the ball axis change since the last poll
+ This returns 0, or -1 if you passed it invalid parameters.
+ The ball indices start at index 0. }
+
+function SDL_JoystickGetBall(joystick: PSDL_Joystick; ball: Integer; var dx: Integer; var dy: Integer): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_JoystickGetBall'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_JoystickGetBall}
+
+{ Get the current state of a button on a joystick
+ The button indices start at index 0. }
+function SDL_JoystickGetButton( joystick: PSDL_Joystick; Button: Integer): UInt8;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_JoystickGetButton'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_JoystickGetButton}
+
+{ Close a joystick previously opened with SDL_JoystickOpen() }
+procedure SDL_JoystickClose(joystick: PSDL_Joystick);
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_JoystickClose'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_JoystickClose}
+
+{------------------------------------------------------------------------------}
+{ event-handling }
+{------------------------------------------------------------------------------}
+
+{ Pumps the event loop, gathering events from the input devices.
+ This function updates the event queue and internal input device state.
+ This should only be run in the thread that sets the video mode. }
+
+procedure SDL_PumpEvents;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_PumpEvents'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_PumpEvents;}
+
+{ Checks the event queue for messages and optionally returns them.
+ If 'action' is SDL_ADDEVENT, up to 'numevents' events will be added to
+ the back of the event queue.
+ If 'action' is SDL_PEEKEVENT, up to 'numevents' events at the front
+ of the event queue, matching 'mask', will be returned and will not
+ be removed from the queue.
+ If 'action' is SDL_GETEVENT, up to 'numevents' events at the front
+ of the event queue, matching 'mask', will be returned and will be
+ removed from the queue.
+ This function returns the number of events actually stored, or -1
+ if there was an error. This function is thread-safe. }
+
+function SDL_PeepEvents(events: PSDL_Event; numevents: Integer; action: TSDL_eventaction; mask: UInt32): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_PeepEvents'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_PeepEvents}
+
+{ Polls for currently pending events, and returns 1 if there are any pending
+ events, or 0 if there are none available. If 'event' is not NULL, the next
+ event is removed from the queue and stored in that area. }
+
+function SDL_PollEvent(event: PSDL_Event): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_PollEvent'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_PollEvent}
+
+{ Waits indefinitely for the next available event, returning 1, or 0 if there
+ was an error while waiting for events. If 'event' is not NULL, the next
+ event is removed from the queue and stored in that area. }
+
+function SDL_WaitEvent(event: PSDL_Event): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_WaitEvent'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_WaitEvent}
+
+function SDL_PushEvent( event : PSDL_Event ) : Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_PushEvent'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_PushEvent}
+
+{ If the filter returns 1, then the event will be added to the internal queue.
+ If it returns 0, then the event will be dropped from the queue, but the
+ internal state will still be updated. This allows selective filtering of
+ dynamically arriving events.
+
+ WARNING: Be very careful of what you do in the event filter function, as
+ it may run in a different thread!
+
+ There is one caveat when dealing with the SDL_QUITEVENT event type. The
+ event filter is only called when the window manager desires to close the
+ application window. If the event filter returns 1, then the window will
+ be closed, otherwise the window will remain open if possible.
+ If the quit event is generated by an interrupt signal, it will bypass the
+ internal queue and be delivered to the application at the next event poll. }
+procedure SDL_SetEventFilter( filter : TSDL_EventFilter );
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_SetEventFilter'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_SetEventFilter}
+
+{ Return the current event filter - can be used to "chain" filters.
+ If there is no event filter set, this function returns NULL. }
+
+function SDL_GetEventFilter: TSDL_EventFilter;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_GetEventFilter'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_GetEventFilter}
+
+{ This function allows you to set the state of processing certain events.
+ If 'state' is set to SDL_IGNORE, that event will be automatically dropped
+ from the event queue and will not event be filtered.
+ If 'state' is set to SDL_ENABLE, that event will be processed normally.
+ If 'state' is set to SDL_QUERY, SDL_EventState() will return the
+ current processing state of the specified event. }
+
+function SDL_EventState(type_: UInt8; state: Integer): UInt8;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_EventState'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_EventState}
+
+{------------------------------------------------------------------------------}
+{ Version Routines }
+{------------------------------------------------------------------------------}
+
+{ This macro can be used to fill a version structure with the compile-time
+ version of the SDL library. }
+procedure SDL_VERSION(var X: TSDL_Version);
+{$EXTERNALSYM SDL_VERSION}
+
+{ This macro turns the version numbers into a numeric value:
+ (1,2,3) -> (1203)
+ This assumes that there will never be more than 100 patchlevels }
+
+function SDL_VERSIONNUM(X, Y, Z: Integer): Integer;
+{$EXTERNALSYM SDL_VERSIONNUM}
+
+// This is the version number macro for the current SDL version
+function SDL_COMPILEDVERSION: Integer;
+{$EXTERNALSYM SDL_COMPILEDVERSION}
+
+// This macro will evaluate to true if compiled with SDL at least X.Y.Z
+function SDL_VERSION_ATLEAST(X: Integer; Y: Integer; Z: Integer) : LongBool;
+{$EXTERNALSYM SDL_VERSION_ATLEAST}
+
+{ This function gets the version of the dynamically linked SDL library.
+ it should NOT be used to fill a version structure, instead you should
+ use the SDL_Version() macro. }
+
+function SDL_Linked_Version: PSDL_version;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_Linked_Version'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_Linked_Version}
+
+{------------------------------------------------------------------------------}
+{ video }
+{------------------------------------------------------------------------------}
+
+{ These functions are used internally, and should not be used unless you
+ have a specific need to specify the video driver you want to use.
+ You should normally use SDL_Init() or SDL_InitSubSystem().
+
+ SDL_VideoInit() initializes the video subsystem -- sets up a connection
+ to the window manager, etc, and determines the current video mode and
+ pixel format, but does not initialize a window or graphics mode.
+ Note that event handling is activated by this routine.
+
+ If you use both sound and video in your application, you need to call
+ SDL_Init() before opening the sound device, otherwise under Win32 DirectX,
+ you won't be able to set full-screen display modes. }
+
+function SDL_VideoInit(driver_name: PChar; flags: UInt32): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_VideoInit'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_VideoInit}
+procedure SDL_VideoQuit;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_VideoQuit'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_VideoQuit}
+
+{ This function fills the given character buffer with the name of the
+ video driver, and returns a pointer to it if the video driver has
+ been initialized. It returns NULL if no driver has been initialized. }
+
+function SDL_VideoDriverName(namebuf: PChar; maxlen: Integer): PChar;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_VideoDriverName'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_VideoDriverName}
+
+{ This function returns a pointer to the current display surface.
+ If SDL is doing format conversion on the display surface, this
+ function returns the publicly visible surface, not the real video
+ surface. }
+
+function SDL_GetVideoSurface: PSDL_Surface;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_GetVideoSurface'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_GetVideoSurface}
+
+{ This function returns a read-only pointer to information about the
+ video hardware. If this is called before SDL_SetVideoMode(), the 'vfmt'
+ member of the returned structure will contain the pixel format of the
+ "best" video mode. }
+function SDL_GetVideoInfo: PSDL_VideoInfo;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_GetVideoInfo'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_GetVideoInfo}
+
+{ Check to see if a particular video mode is supported.
+ It returns 0 if the requested mode is not supported under any bit depth,
+ or returns the bits-per-pixel of the closest available mode with the
+ given width and height. If this bits-per-pixel is different from the
+ one used when setting the video mode, SDL_SetVideoMode() will succeed,
+ but will emulate the requested bits-per-pixel with a shadow surface.
+
+ The arguments to SDL_VideoModeOK() are the same ones you would pass to
+ SDL_SetVideoMode() }
+
+function SDL_VideoModeOK(width, height, bpp: Integer; flags: UInt32): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_VideoModeOK'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_VideoModeOK}
+
+{ Return a pointer to an array of available screen dimensions for the
+ given format and video flags, sorted largest to smallest. Returns
+ NULL if there are no dimensions available for a particular format,
+ or (SDL_Rect **)-1 if any dimension is okay for the given format.
+
+ if 'format' is NULL, the mode list will be for the format given
+ by SDL_GetVideoInfo( ) - > vfmt }
+
+function SDL_ListModes(format: PSDL_PixelFormat; flags: UInt32): PPSDL_Rect;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_ListModes'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_ListModes}
+
+
+{ Set up a video mode with the specified width, height and bits-per-pixel.
+
+ If 'bpp' is 0, it is treated as the current display bits per pixel.
+
+ If SDL_ANYFORMAT is set in 'flags', the SDL library will try to set the
+ requested bits-per-pixel, but will return whatever video pixel format is
+ available. The default is to emulate the requested pixel format if it
+ is not natively available.
+
+ If SDL_HWSURFACE is set in 'flags', the video surface will be placed in
+ video memory, if possible, and you may have to call SDL_LockSurface()
+ in order to access the raw framebuffer. Otherwise, the video surface
+ will be created in system memory.
+
+ If SDL_ASYNCBLIT is set in 'flags', SDL will try to perform rectangle
+ updates asynchronously, but you must always lock before accessing pixels.
+ SDL will wait for updates to complete before returning from the lock.
+
+ If SDL_HWPALETTE is set in 'flags', the SDL library will guarantee
+ that the colors set by SDL_SetColors() will be the colors you get.
+ Otherwise, in 8-bit mode, SDL_SetColors() may not be able to set all
+ of the colors exactly the way they are requested, and you should look
+ at the video surface structure to determine the actual palette.
+ If SDL cannot guarantee that the colors you request can be set,
+ i.e. if the colormap is shared, then the video surface may be created
+ under emulation in system memory, overriding the SDL_HWSURFACE flag.
+
+ If SDL_FULLSCREEN is set in 'flags', the SDL library will try to set
+ a fullscreen video mode. The default is to create a windowed mode
+ if the current graphics system has a window manager.
+ If the SDL library is able to set a fullscreen video mode, this flag
+ will be set in the surface that is returned.
+
+ If SDL_DOUBLEBUF is set in 'flags', the SDL library will try to set up
+ two surfaces in video memory and swap between them when you call
+ SDL_Flip(). This is usually slower than the normal single-buffering
+ scheme, but prevents "tearing" artifacts caused by modifying video
+ memory while the monitor is refreshing. It should only be used by
+ applications that redraw the entire screen on every update.
+
+ This function returns the video framebuffer surface, or NULL if it fails. }
+
+function SDL_SetVideoMode(width, height, bpp: Integer; flags: UInt32): PSDL_Surface;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_SetVideoMode'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_SetVideoMode}
+
+
+{ Makes sure the given list of rectangles is updated on the given screen.
+ If 'x', 'y', 'w' and 'h' are all 0, SDL_UpdateRect will update the entire
+ screen.
+ These functions should not be called while 'screen' is locked. }
+
+procedure SDL_UpdateRects(screen: PSDL_Surface; numrects: Integer; rects: PSDL_Rect);
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_UpdateRects'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_UpdateRects}
+procedure SDL_UpdateRect(screen: PSDL_Surface; x, y: SInt32; w, h: UInt32);
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_UpdateRect'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_UpdateRect}
+
+
+{ On hardware that supports double-buffering, this function sets up a flip
+ and returns. The hardware will wait for vertical retrace, and then swap
+ video buffers before the next video surface blit or lock will return.
+ On hardware that doesn not support double-buffering, this is equivalent
+ to calling SDL_UpdateRect(screen, 0, 0, 0, 0);
+ The SDL_DOUBLEBUF flag must have been passed to SDL_SetVideoMode() when
+ setting the video mode for this function to perform hardware flipping.
+ This function returns 0 if successful, or -1 if there was an error.}
+
+function SDL_Flip(screen: PSDL_Surface): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_Flip'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_Flip}
+
+{ Set the gamma correction for each of the color channels.
+ The gamma values range (approximately) between 0.1 and 10.0
+
+ If this function isn't supported directly by the hardware, it will
+ be emulated using gamma ramps, if available. If successful, this
+ function returns 0, otherwise it returns -1. }
+
+function SDL_SetGamma(redgamma: single; greengamma: single; bluegamma: single ): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_SetGamma'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_SetGamma}
+
+{ Set the gamma translation table for the red, green, and blue channels
+ of the video hardware. Each table is an array of 256 16-bit quantities,
+ representing a mapping between the input and output for that channel.
+ The input is the index into the array, and the output is the 16-bit
+ gamma value at that index, scaled to the output color precision.
+
+ You may pass NULL for any of the channels to leave it unchanged.
+ If the call succeeds, it will return 0. If the display driver or
+ hardware does not support gamma translation, or otherwise fails,
+ this function will return -1. }
+
+function SDL_SetGammaRamp( redtable: PUInt16; greentable: PUInt16; bluetable: PUInt16): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_SetGammaRamp'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_SetGammaRamp}
+
+{ Retrieve the current values of the gamma translation tables.
+
+ You must pass in valid pointers to arrays of 256 16-bit quantities.
+ Any of the pointers may be NULL to ignore that channel.
+ If the call succeeds, it will return 0. If the display driver or
+ hardware does not support gamma translation, or otherwise fails,
+ this function will return -1. }
+
+function SDL_GetGammaRamp( redtable: PUInt16; greentable: PUInt16; bluetable: PUInt16): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_GetGammaRamp'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_GetGammaRamp}
+
+{ Sets a portion of the colormap for the given 8-bit surface. If 'surface'
+ is not a palettized surface, this function does nothing, returning 0.
+ If all of the colors were set as passed to SDL_SetColors(), it will
+ return 1. If not all the color entries were set exactly as given,
+ it will return 0, and you should look at the surface palette to
+ determine the actual color palette.
+
+ When 'surface' is the surface associated with the current display, the
+ display colormap will be updated with the requested colors. If
+ SDL_HWPALETTE was set in SDL_SetVideoMode() flags, SDL_SetColors()
+ will always return 1, and the palette is guaranteed to be set the way
+ you desire, even if the window colormap has to be warped or run under
+ emulation. }
+
+
+function SDL_SetColors(surface: PSDL_Surface; colors: PSDL_Color; firstcolor : Integer; ncolors: Integer) : Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_SetColors'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_SetColors}
+
+{ Sets a portion of the colormap for a given 8-bit surface.
+ 'flags' is one or both of:
+ SDL_LOGPAL -- set logical palette, which controls how blits are mapped
+ to/from the surface,
+ SDL_PHYSPAL -- set physical palette, which controls how pixels look on
+ the screen
+ Only screens have physical palettes. Separate change of physical/logical
+ palettes is only possible if the screen has SDL_HWPALETTE set.
+
+ The return value is 1 if all colours could be set as requested, and 0
+ otherwise.
+
+ SDL_SetColors() is equivalent to calling this function with
+ flags = (SDL_LOGPAL or SDL_PHYSPAL). }
+
+function SDL_SetPalette(surface: PSDL_Surface; flags: Integer; colors: PSDL_Color; firstcolor: Integer; ncolors: Integer): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_SetPalette'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_SetPalette}
+
+{ Maps an RGB triple to an opaque pixel value for a given pixel format }
+function SDL_MapRGB(format: PSDL_PixelFormat; r: UInt8; g: UInt8; b: UInt8) : UInt32;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_MapRGB'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_MapRGB}
+
+{ Maps an RGBA quadruple to a pixel value for a given pixel format }
+function SDL_MapRGBA(format: PSDL_PixelFormat; r: UInt8; g: UInt8; b: UInt8; a: UInt8): UInt32;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_MapRGBA'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_MapRGBA}
+
+{ Maps a pixel value into the RGB components for a given pixel format }
+procedure SDL_GetRGB(pixel: UInt32; fmt: PSDL_PixelFormat; r: PUInt8; g: PUInt8; b: PUInt8);
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_GetRGB'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_GetRGB}
+
+{ Maps a pixel value into the RGBA components for a given pixel format }
+procedure SDL_GetRGBA(pixel: UInt32; fmt: PSDL_PixelFormat; r: PUInt8; g: PUInt8; b: PUInt8; a: PUInt8);
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_GetRGBA'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_GetRGBA}
+
+{ Allocate and free an RGB surface (must be called after SDL_SetVideoMode)
+ If the depth is 4 or 8 bits, an empty palette is allocated for the surface.
+ If the depth is greater than 8 bits, the pixel format is set using the
+ flags '[RGB]mask'.
+ If the function runs out of memory, it will return NULL.
+
+ The 'flags' tell what kind of surface to create.
+ SDL_SWSURFACE means that the surface should be created in system memory.
+ SDL_HWSURFACE means that the surface should be created in video memory,
+ with the same format as the display surface. This is useful for surfaces
+ that will not change much, to take advantage of hardware acceleration
+ when being blitted to the display surface.
+ SDL_ASYNCBLIT means that SDL will try to perform asynchronous blits with
+ this surface, but you must always lock it before accessing the pixels.
+ SDL will wait for current blits to finish before returning from the lock.
+ SDL_SRCCOLORKEY indicates that the surface will be used for colorkey blits.
+ If the hardware supports acceleration of colorkey blits between
+ two surfaces in video memory, SDL will try to place the surface in
+ video memory. If this isn't possible or if there is no hardware
+ acceleration available, the surface will be placed in system memory.
+ SDL_SRCALPHA means that the surface will be used for alpha blits and
+ if the hardware supports hardware acceleration of alpha blits between
+ two surfaces in video memory, to place the surface in video memory
+ if possible, otherwise it will be placed in system memory.
+ If the surface is created in video memory, blits will be _much_ faster,
+ but the surface format must be identical to the video surface format,
+ and the only way to access the pixels member of the surface is to use
+ the SDL_LockSurface() and SDL_UnlockSurface() calls.
+ If the requested surface actually resides in video memory, SDL_HWSURFACE
+ will be set in the flags member of the returned surface. If for some
+ reason the surface could not be placed in video memory, it will not have
+ the SDL_HWSURFACE flag set, and will be created in system memory instead. }
+
+function SDL_AllocSurface(flags: UInt32; width, height, depth: Integer;
+ RMask, GMask, BMask, AMask: UInt32): PSDL_Surface;
+{$EXTERNALSYM SDL_AllocSurface}
+
+function SDL_CreateRGBSurface(flags: UInt32; width, height, depth: Integer; RMask, GMask, BMask, AMask: UInt32): PSDL_Surface;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_CreateRGBSurface'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_CreateRGBSurface}
+
+function SDL_CreateRGBSurfaceFrom(pixels: Pointer; width, height, depth, pitch
+ : Integer; RMask, GMask, BMask, AMask: UInt32): PSDL_Surface;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_CreateRGBSurfaceFrom'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_CreateRGBSurfaceFrom}
+
+procedure SDL_FreeSurface(surface: PSDL_Surface);
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_FreeSurface'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_FreeSurface}
+
+function SDL_MustLock(Surface: PSDL_Surface): Boolean;
+{$EXTERNALSYM SDL_MustLock}
+{ SDL_LockSurface() sets up a surface for directly accessing the pixels.
+ Between calls to SDL_LockSurface()/SDL_UnlockSurface(), you can write
+ to and read from 'surface->pixels', using the pixel format stored in
+ 'surface->format'. Once you are done accessing the surface, you should
+ use SDL_UnlockSurface() to release it.
+
+ Not all surfaces require locking. If SDL_MUSTLOCK(surface) evaluates
+ to 0, then you can read and write to the surface at any time, and the
+ pixel format of the surface will not change. In particular, if the
+ SDL_HWSURFACE flag is not given when calling SDL_SetVideoMode(), you
+ will not need to lock the display surface before accessing it.
+
+ No operating system or library calls should be made between lock/unlock
+ pairs, as critical system locks may be held during this time.
+
+ SDL_LockSurface() returns 0, or -1 if the surface couldn't be locked. }
+function SDL_LockSurface(surface: PSDL_Surface): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_LockSurface'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_LockSurface}
+
+procedure SDL_UnlockSurface(surface: PSDL_Surface);
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_UnlockSurface'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_UnlockSurface}
+
+{ Load a surface from a seekable SDL data source (memory or file.)
+ If 'freesrc' is non-zero, the source will be closed after being read.
+ Returns the new surface, or NULL if there was an error.
+ The new surface should be freed with SDL_FreeSurface(). }
+function SDL_LoadBMP_RW(src: PSDL_RWops; freesrc: Integer): PSDL_Surface;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_LoadBMP_RW'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_LoadBMP_RW}
+
+// Convenience macro -- load a surface from a file
+function SDL_LoadBMP(filename: PChar): PSDL_Surface;
+{$EXTERNALSYM SDL_LoadBMP}
+
+{ Save a surface to a seekable SDL data source (memory or file.)
+ If 'freedst' is non-zero, the source will be closed after being written.
+ Returns 0 if successful or -1 if there was an error. }
+
+function SDL_SaveBMP_RW(surface: PSDL_Surface; dst: PSDL_RWops; freedst: Integer): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_SaveBMP_RW'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_SaveBMP_RW}
+
+// Convenience macro -- save a surface to a file
+function SDL_SaveBMP(surface: PSDL_Surface; filename: PChar): Integer;
+{$EXTERNALSYM SDL_SaveBMP}
+
+{ Sets the color key (transparent pixel) in a blittable surface.
+ If 'flag' is SDL_SRCCOLORKEY (optionally OR'd with SDL_RLEACCEL),
+ 'key' will be the transparent pixel in the source image of a blit.
+ SDL_RLEACCEL requests RLE acceleration for the surface if present,
+ and removes RLE acceleration if absent.
+ If 'flag' is 0, this function clears any current color key.
+ This function returns 0, or -1 if there was an error. }
+
+function SDL_SetColorKey(surface: PSDL_Surface; flag, key: UInt32) : Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_SetColorKey'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_SetColorKey}
+
+{ This function sets the alpha value for the entire surface, as opposed to
+ using the alpha component of each pixel. This value measures the range
+ of transparency of the surface, 0 being completely transparent to 255
+ being completely opaque. An 'alpha' value of 255 causes blits to be
+ opaque, the source pixels copied to the destination (the default). Note
+ that per-surface alpha can be combined with colorkey transparency.
+
+ If 'flag' is 0, alpha blending is disabled for the surface.
+ If 'flag' is SDL_SRCALPHA, alpha blending is enabled for the surface.
+ OR:ing the flag with SDL_RLEACCEL requests RLE acceleration for the
+ surface; if SDL_RLEACCEL is not specified, the RLE accel will be removed. }
+
+
+function SDL_SetAlpha(surface: PSDL_Surface; flag: UInt32; alpha: UInt8): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_SetAlpha'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_SetAlpha}
+
+{ Sets the clipping rectangle for the destination surface in a blit.
+
+ If the clip rectangle is NULL, clipping will be disabled.
+ If the clip rectangle doesn't intersect the surface, the function will
+ return SDL_FALSE and blits will be completely clipped. Otherwise the
+ function returns SDL_TRUE and blits to the surface will be clipped to
+ the intersection of the surface area and the clipping rectangle.
+
+ Note that blits are automatically clipped to the edges of the source
+ and destination surfaces. }
+procedure SDL_SetClipRect(surface: PSDL_Surface; rect: PSDL_Rect); cdecl;
+external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_SetClipRect'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_SetClipRect}
+
+{ Gets the clipping rectangle for the destination surface in a blit.
+ 'rect' must be a pointer to a valid rectangle which will be filled
+ with the correct values. }
+procedure SDL_GetClipRect(surface: PSDL_Surface; rect: PSDL_Rect); cdecl;
+external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_GetClipRect'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_GetClipRect}
+
+{ Creates a new surface of the specified format, and then copies and maps
+ the given surface to it so the blit of the converted surface will be as
+ fast as possible. If this function fails, it returns NULL.
+
+ The 'flags' parameter is passed to SDL_CreateRGBSurface() and has those
+ semantics. You can also pass SDL_RLEACCEL in the flags parameter and
+ SDL will try to RLE accelerate colorkey and alpha blits in the resulting
+ surface.
+
+ This function is used internally by SDL_DisplayFormat(). }
+
+function SDL_ConvertSurface(src: PSDL_Surface; fmt: PSDL_PixelFormat; flags: UInt32): PSDL_Surface;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_ConvertSurface'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_ConvertSurface}
+
+{
+ This performs a fast blit from the source surface to the destination
+ surface. It assumes that the source and destination rectangles are
+ the same size. If either 'srcrect' or 'dstrect' are NULL, the entire
+ surface (src or dst) is copied. The final blit rectangles are saved
+ in 'srcrect' and 'dstrect' after all clipping is performed.
+ If the blit is successful, it returns 0, otherwise it returns -1.
+
+ The blit function should not be called on a locked surface.
+
+ The blit semantics for surfaces with and without alpha and colorkey
+ are defined as follows:
+
+ RGBA->RGB:
+ SDL_SRCALPHA set:
+ alpha-blend (using alpha-channel).
+ SDL_SRCCOLORKEY ignored.
+ SDL_SRCALPHA not set:
+ copy RGB.
+ if SDL_SRCCOLORKEY set, only copy the pixels matching the
+ RGB values of the source colour key, ignoring alpha in the
+ comparison.
+
+ RGB->RGBA:
+ SDL_SRCALPHA set:
+ alpha-blend (using the source per-surface alpha value);
+ set destination alpha to opaque.
+ SDL_SRCALPHA not set:
+ copy RGB, set destination alpha to opaque.
+ both:
+ if SDL_SRCCOLORKEY set, only copy the pixels matching the
+ source colour key.
+
+ RGBA->RGBA:
+ SDL_SRCALPHA set:
+ alpha-blend (using the source alpha channel) the RGB values;
+ leave destination alpha untouched. [Note: is this correct?]
+ SDL_SRCCOLORKEY ignored.
+ SDL_SRCALPHA not set:
+ copy all of RGBA to the destination.
+ if SDL_SRCCOLORKEY set, only copy the pixels matching the
+ RGB values of the source colour key, ignoring alpha in the
+ comparison.
+
+ RGB->RGB:
+ SDL_SRCALPHA set:
+ alpha-blend (using the source per-surface alpha value).
+ SDL_SRCALPHA not set:
+ copy RGB.
+ both:
+ if SDL_SRCCOLORKEY set, only copy the pixels matching the
+ source colour key.
+
+ If either of the surfaces were in video memory, and the blit returns -2,
+ the video memory was lost, so it should be reloaded with artwork and
+ re-blitted:
+ while ( SDL_BlitSurface(image, imgrect, screen, dstrect) = -2 ) do
+ begin
+ while ( SDL_LockSurface(image) < 0 ) do
+ Sleep(10);
+ -- Write image pixels to image->pixels --
+ SDL_UnlockSurface(image);
+ end;
+
+ This happens under DirectX 5.0 when the system switches away from your
+ fullscreen application. The lock will also fail until you have access
+ to the video memory again. }
+
+{ You should call SDL_BlitSurface() unless you know exactly how SDL
+ blitting works internally and how to use the other blit functions. }
+
+function SDL_BlitSurface(src: PSDL_Surface; srcrect: PSDL_Rect; dst: PSDL_Surface; dstrect: PSDL_Rect): Integer;
+{$EXTERNALSYM SDL_BlitSurface}
+
+{ This is the public blit function, SDL_BlitSurface(), and it performs
+ rectangle validation and clipping before passing it to SDL_LowerBlit() }
+function SDL_UpperBlit(src: PSDL_Surface; srcrect: PSDL_Rect; dst: PSDL_Surface; dstrect: PSDL_Rect): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_UpperBlit'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_UpperBlit}
+
+{ This is a semi-private blit function and it performs low-level surface
+ blitting only. }
+function SDL_LowerBlit(src: PSDL_Surface; srcrect: PSDL_Rect; dst: PSDL_Surface; dstrect: PSDL_Rect): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_LowerBlit'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_LowerBlit}
+
+{ This function performs a fast fill of the given rectangle with 'color'
+ The given rectangle is clipped to the destination surface clip area
+ and the final fill rectangle is saved in the passed in pointer.
+ If 'dstrect' is NULL, the whole surface will be filled with 'color'
+ The color should be a pixel of the format used by the surface, and
+ can be generated by the SDL_MapRGB() function.
+ This function returns 0 on success, or -1 on error. }
+
+function SDL_FillRect(dst: PSDL_Surface; dstrect: PSDL_Rect; color: UInt32) : Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_FillRect'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_FillRect}
+
+{ This function takes a surface and copies it to a new surface of the
+ pixel format and colors of the video framebuffer, suitable for fast
+ blitting onto the display surface. It calls SDL_ConvertSurface()
+
+ If you want to take advantage of hardware colorkey or alpha blit
+ acceleration, you should set the colorkey and alpha value before
+ calling this function.
+
+ If the conversion fails or runs out of memory, it returns NULL }
+
+function SDL_DisplayFormat(surface: PSDL_Surface): PSDL_Surface; cdecl;
+external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_DisplayFormat'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_DisplayFormat}
+
+{ This function takes a surface and copies it to a new surface of the
+ pixel format and colors of the video framebuffer (if possible),
+ suitable for fast alpha blitting onto the display surface.
+ The new surface will always have an alpha channel.
+
+ If you want to take advantage of hardware colorkey or alpha blit
+ acceleration, you should set the colorkey and alpha value before
+ calling this function.
+
+ If the conversion fails or runs out of memory, it returns NULL }
+
+
+function SDL_DisplayFormatAlpha(surface: PSDL_Surface): PSDL_Surface; cdecl;
+external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_DisplayFormatAlpha'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_DisplayFormatAlpha}
+
+//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+//* YUV video surface overlay functions */
+//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+{ This function creates a video output overlay
+ Calling the returned surface an overlay is something of a misnomer because
+ the contents of the display surface underneath the area where the overlay
+ is shown is undefined - it may be overwritten with the converted YUV data. }
+
+function SDL_CreateYUVOverlay(width: Integer; height: Integer; format: UInt32; display: PSDL_Surface): PSDL_Overlay;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_CreateYUVOverlay'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_CreateYUVOverlay}
+
+// Lock an overlay for direct access, and unlock it when you are done
+function SDL_LockYUVOverlay(Overlay: PSDL_Overlay): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_LockYUVOverlay'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_LockYUVOverlay}
+
+procedure SDL_UnlockYUVOverlay(Overlay: PSDL_Overlay); cdecl;
+external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_UnlockYUVOverlay'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_UnlockYUVOverlay}
+
+
+{ Blit a video overlay to the display surface.
+ The contents of the video surface underneath the blit destination are
+ not defined.
+ The width and height of the destination rectangle may be different from
+ that of the overlay, but currently only 2x scaling is supported. }
+
+function SDL_DisplayYUVOverlay(Overlay: PSDL_Overlay; dstrect: PSDL_Rect) : Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_DisplayYUVOverlay'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_DisplayYUVOverlay}
+
+// Free a video overlay
+procedure SDL_FreeYUVOverlay(Overlay: PSDL_Overlay);
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_FreeYUVOverlay'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_FreeYUVOverlay}
+
+{------------------------------------------------------------------------------}
+{ OpenGL Routines }
+{------------------------------------------------------------------------------}
+
+{ Dynamically load a GL driver, if SDL is built with dynamic GL.
+
+ SDL links normally with the OpenGL library on your system by default,
+ but you can compile it to dynamically load the GL driver at runtime.
+ If you do this, you need to retrieve all of the GL functions used in
+ your program from the dynamic library using SDL_GL_GetProcAddress().
+
+ This is disabled in default builds of SDL. }
+
+
+function SDL_GL_LoadLibrary(filename: PChar): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_GL_LoadLibrary'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_GL_LoadLibrary}
+
+{ Get the address of a GL function (for extension functions) }
+function SDL_GL_GetProcAddress(procname: PChar) : Pointer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_GL_GetProcAddress'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_GL_GetProcAddress}
+
+{ Set an attribute of the OpenGL subsystem before intialization. }
+function SDL_GL_SetAttribute(attr: TSDL_GLAttr; value: Integer) : Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_GL_SetAttribute'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_GL_SetAttribute}
+
+{ Get an attribute of the OpenGL subsystem from the windowing
+ interface, such as glX. This is of course different from getting
+ the values from SDL's internal OpenGL subsystem, which only
+ stores the values you request before initialization.
+
+ Developers should track the values they pass into SDL_GL_SetAttribute
+ themselves if they want to retrieve these values. }
+
+function SDL_GL_GetAttribute(attr: TSDL_GLAttr; var value: Integer): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_GL_GetAttribute'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_GL_GetAttribute}
+
+{ Swap the OpenGL buffers, if double-buffering is supported. }
+
+procedure SDL_GL_SwapBuffers;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_GL_SwapBuffers'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_GL_SwapBuffers;}
+
+{ Internal functions that should not be called unless you have read
+ and understood the source code for these functions. }
+
+procedure SDL_GL_UpdateRects(numrects: Integer; rects: PSDL_Rect);
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_GL_UpdateRects'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_GL_UpdateRects}
+procedure SDL_GL_Lock;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_GL_Lock'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_GL_Lock;}
+procedure SDL_GL_Unlock;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_GL_Unlock'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_GL_Unlock;}
+
+{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
+{* These functions allow interaction with the window manager, if any. *}
+{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
+
+{ Sets/Gets the title and icon text of the display window }
+procedure SDL_WM_GetCaption(var title : PChar; var icon : PChar);
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_WM_GetCaption'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_WM_GetCaption}
+procedure SDL_WM_SetCaption( const title : PChar; const icon : PChar);
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_WM_SetCaption'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_WM_SetCaption}
+
+{ Sets the icon for the display window.
+ This function must be called before the first call to SDL_SetVideoMode().
+ It takes an icon surface, and a mask in MSB format.
+ If 'mask' is NULL, the entire icon surface will be used as the icon. }
+procedure SDL_WM_SetIcon(icon: PSDL_Surface; mask: UInt8);
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_WM_SetIcon'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_WM_SetIcon}
+
+{ This function iconifies the window, and returns 1 if it succeeded.
+ If the function succeeds, it generates an SDL_APPACTIVE loss event.
+ This function is a noop and returns 0 in non-windowed environments. }
+
+function SDL_WM_IconifyWindow: Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_WM_IconifyWindow'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_WM_IconifyWindow}
+
+{ Toggle fullscreen mode without changing the contents of the screen.
+ If the display surface does not require locking before accessing
+ the pixel information, then the memory pointers will not change.
+
+ If this function was able to toggle fullscreen mode (change from
+ running in a window to fullscreen, or vice-versa), it will return 1.
+ If it is not implemented, or fails, it returns 0.
+
+ The next call to SDL_SetVideoMode() will set the mode fullscreen
+ attribute based on the flags parameter - if SDL_FULLSCREEN is not
+ set, then the display will be windowed by default where supported.
+
+ This is currently only implemented in the X11 video driver. }
+
+function SDL_WM_ToggleFullScreen(surface: PSDL_Surface): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_WM_ToggleFullScreen'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_WM_ToggleFullScreen}
+
+{ Grabbing means that the mouse is confined to the application window,
+ and nearly all keyboard input is passed directly to the application,
+ and not interpreted by a window manager, if any. }
+
+function SDL_WM_GrabInput(mode: TSDL_GrabMode): TSDL_GrabMode;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_WM_GrabInput'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_WM_GrabInput}
+
+{------------------------------------------------------------------------------}
+{ mouse-routines }
+{------------------------------------------------------------------------------}
+
+{ Retrieve the current state of the mouse.
+ The current button state is returned as a button bitmask, which can
+ be tested using the SDL_BUTTON(X) macros, and x and y are set to the
+ current mouse cursor position. You can pass NULL for either x or y. }
+
+function SDL_GetMouseState(var x: Integer; var y: Integer): UInt8;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_GetMouseState'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_GetMouseState}
+
+{ Retrieve the current state of the mouse.
+ The current button state is returned as a button bitmask, which can
+ be tested using the SDL_BUTTON(X) macros, and x and y are set to the
+ mouse deltas since the last call to SDL_GetRelativeMouseState(). }
+function SDL_GetRelativeMouseState(var x: Integer; var y: Integer): UInt8;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_GetRelativeMouseState'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_GetRelativeMouseState}
+
+{ Set the position of the mouse cursor (generates a mouse motion event) }
+procedure SDL_WarpMouse(x, y: UInt16);
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_WarpMouse'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_WarpMouse}
+
+{ Create a cursor using the specified data and mask (in MSB format).
+ The cursor width must be a multiple of 8 bits.
+
+ The cursor is created in black and white according to the following:
+ data mask resulting pixel on screen
+ 0 1 White
+ 1 1 Black
+ 0 0 Transparent
+ 1 0 Inverted color if possible, black if not.
+
+ Cursors created with this function must be freed with SDL_FreeCursor(). }
+function SDL_CreateCursor(data, mask: PUInt8; w, h, hot_x, hot_y: Integer): PSDL_Cursor;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_CreateCursor'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_CreateCursor}
+
+{ Set the currently active cursor to the specified one.
+ If the cursor is currently visible, the change will be immediately
+ represented on the display. }
+procedure SDL_SetCursor(cursor: PSDL_Cursor);
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_SetCursor'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_SetCursor}
+
+{ Returns the currently active cursor. }
+function SDL_GetCursor: PSDL_Cursor;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_GetCursor'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_GetCursor}
+
+{ Deallocates a cursor created with SDL_CreateCursor(). }
+procedure SDL_FreeCursor(cursor: PSDL_Cursor);
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_FreeCursor'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_FreeCursor}
+
+{ Toggle whether or not the cursor is shown on the screen.
+ The cursor start off displayed, but can be turned off.
+ SDL_ShowCursor() returns 1 if the cursor was being displayed
+ before the call, or 0 if it was not. You can query the current
+ state by passing a 'toggle' value of -1. }
+function SDL_ShowCursor(toggle: Integer): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_ShowCursor'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_ShowCursor}
+
+function SDL_BUTTON( Button : Integer ) : Integer;
+
+{------------------------------------------------------------------------------}
+{ Keyboard-routines }
+{------------------------------------------------------------------------------}
+
+{ Enable/Disable UNICODE translation of keyboard input.
+ This translation has some overhead, so translation defaults off.
+ If 'enable' is 1, translation is enabled.
+ If 'enable' is 0, translation is disabled.
+ If 'enable' is -1, the translation state is not changed.
+ It returns the previous state of keyboard translation. }
+function SDL_EnableUNICODE(enable: Integer): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_EnableUNICODE'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_EnableUNICODE}
+
+{ If 'delay' is set to 0, keyboard repeat is disabled. }
+function SDL_EnableKeyRepeat(delay: Integer; interval: Integer): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_EnableKeyRepeat'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_EnableKeyRepeat}
+
+procedure SDL_GetKeyRepeat(delay : PInteger; interval: PInteger);
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_GetKeyRepeat'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_GetKeyRepeat}
+
+{ Get a snapshot of the current state of the keyboard.
+ Returns an array of keystates, indexed by the SDLK_* syms.
+ Used:
+
+ UInt8 *keystate = SDL_GetKeyState(NULL);
+ if ( keystate[SDLK_RETURN] ) ... <RETURN> is pressed }
+
+function SDL_GetKeyState(numkeys: PInt): PUInt8;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_GetKeyState'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_GetKeyState}
+
+{ Get the current key modifier state }
+function SDL_GetModState: TSDLMod;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_GetModState'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_GetModState}
+
+{ Set the current key modifier state
+ This does not change the keyboard state, only the key modifier flags. }
+procedure SDL_SetModState(modstate: TSDLMod);
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_SetModState'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_SetModState}
+
+{ Get the name of an SDL virtual keysym }
+function SDL_GetKeyName(key: TSDLKey): PChar;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_GetKeyName'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_GetKeyName}
+
+{------------------------------------------------------------------------------}
+{ Active Routines }
+{------------------------------------------------------------------------------}
+
+{ This function returns the current state of the application, which is a
+ bitwise combination of SDL_APPMOUSEFOCUS, SDL_APPINPUTFOCUS, and
+ SDL_APPACTIVE. If SDL_APPACTIVE is set, then the user is able to
+ see your application, otherwise it has been iconified or disabled. }
+
+function SDL_GetAppState: UInt8;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_GetAppState'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_GetAppState}
+
+
+{ Mutex functions }
+
+{ Create a mutex, initialized unlocked }
+
+function SDL_CreateMutex: PSDL_Mutex;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_CreateMutex'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_CreateMutex}
+
+{ Lock the mutex (Returns 0, or -1 on error) }
+
+ function SDL_mutexP(mutex: PSDL_mutex): Integer;
+ cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_mutexP'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{ $ EXTERNALSYM SDL_mutexP}
+
+function SDL_LockMutex(mutex: PSDL_mutex): Integer;
+{$EXTERNALSYM SDL_LockMutex}
+
+{ Unlock the mutex (Returns 0, or -1 on error) }
+function SDL_mutexV(mutex: PSDL_mutex): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_mutexV'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_mutexV}
+
+function SDL_UnlockMutex(mutex: PSDL_mutex): Integer;
+{$EXTERNALSYM SDL_UnlockMutex}
+
+{ Destroy a mutex }
+procedure SDL_DestroyMutex(mutex: PSDL_mutex);
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_DestroyMutex'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_DestroyMutex}
+
+{ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * }
+{ Semaphore functions }
+{ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * }
+{ Create a semaphore, initialized with value, returns NULL on failure. }
+function SDL_CreateSemaphore(initial_value: UInt32): PSDL_Sem;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_CreateSemaphore'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_CreateSemaphore}
+
+
+{ Destroy a semaphore }
+procedure SDL_DestroySemaphore(sem: PSDL_sem);
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_DestroySemaphore'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_DestroySemaphore}
+
+{ This function suspends the calling thread until the semaphore pointed
+ to by sem has a positive count. It then atomically decreases the semaphore
+ count. }
+
+function SDL_SemWait(sem: PSDL_sem): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_SemWait'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_SemWait}
+
+{ Non-blocking variant of SDL_SemWait(), returns 0 if the wait succeeds,
+ SDL_MUTEX_TIMEDOUT if the wait would block, and -1 on error. }
+
+function SDL_SemTryWait(sem: PSDL_sem): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_SemTryWait'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_SemTryWait}
+
+{ Variant of SDL_SemWait() with a timeout in milliseconds, returns 0 if
+ the wait succeeds, SDL_MUTEX_TIMEDOUT if the wait does not succeed in
+ the allotted time, and -1 on error.
+ On some platforms this function is implemented by looping with a delay
+ of 1 ms, and so should be avoided if possible. }
+
+function SDL_SemWaitTimeout(sem: PSDL_sem; ms: UInt32): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_SemWaitTimeout'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_SemTryWait}
+
+{ Atomically increases the semaphore's count (not blocking), returns 0,
+ or -1 on error. }
+
+function SDL_SemPost(sem: PSDL_sem): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_SemPost'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_SemTryWait}
+
+{ Returns the current count of the semaphore }
+
+function SDL_SemValue(sem: PSDL_sem): UInt32;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_SemValue'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_SemValue}
+
+{ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * }
+{ Condition variable functions }
+{ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * }
+{ Create a condition variable }
+function SDL_CreateCond: PSDL_Cond;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_CreateCond'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_CreateCond}
+
+{ Destroy a condition variable }
+procedure SDL_DestroyCond(cond: PSDL_Cond);
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_DestroyCond'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_DestroyCond}
+
+{ Restart one of the threads that are waiting on the condition variable,
+ returns 0 or -1 on error. }
+
+function SDL_CondSignal(cond: PSDL_cond): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_CondSignal'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_CondSignal}
+
+{ Restart all threads that are waiting on the condition variable,
+ returns 0 or -1 on error. }
+
+function SDL_CondBroadcast(cond: PSDL_cond): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_CondBroadcast'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_CondBroadcast}
+
+
+{ Wait on the condition variable, unlocking the provided mutex.
+ The mutex must be locked before entering this function!
+ Returns 0 when it is signaled, or -1 on error. }
+
+function SDL_CondWait(cond: PSDL_cond; mut: PSDL_mutex): Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_CondWait'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_CondWait}
+
+{ Waits for at most 'ms' milliseconds, and returns 0 if the condition
+ variable is signaled, SDL_MUTEX_TIMEDOUT if the condition is not
+ signaled in the allotted time, and -1 on error.
+ On some platforms this function is implemented by looping with a delay
+ of 1 ms, and so should be avoided if possible. }
+
+function SDL_CondWaitTimeout(cond: PSDL_cond; mut: PSDL_mutex; ms: UInt32) : Integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_CondWaitTimeout'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_CondWaitTimeout}
+
+{ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * }
+{ Condition variable functions }
+{ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * }
+
+{ Create a thread }
+function SDL_CreateThread(fn: PInt; data: Pointer): PSDL_Thread;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_CreateThread'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_CreateThread}
+
+{ Get the 32-bit thread identifier for the current thread }
+function SDL_ThreadID: UInt32;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_ThreadID'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_ThreadID}
+
+{ Get the 32-bit thread identifier for the specified thread,
+ equivalent to SDL_ThreadID() if the specified thread is NULL. }
+function SDL_GetThreadID(thread: PSDL_Thread): UInt32;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_GetThreadID'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_GetThreadID}
+
+{ Wait for a thread to finish.
+ The return code for the thread function is placed in the area
+ pointed to by 'status', if 'status' is not NULL. }
+
+procedure SDL_WaitThread(thread: PSDL_Thread; var status: Integer);
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_WaitThread'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_WaitThread}
+
+{ Forcefully kill a thread without worrying about its state }
+procedure SDL_KillThread(thread: PSDL_Thread);
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_KillThread'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_KillThread}
+
+{------------------------------------------------------------------------------}
+{ Get Environment Routines }
+{------------------------------------------------------------------------------}
+{$IFDEF WINDOWS}
+function _putenv( const variable : Pchar ): integer;
+cdecl;
+{$ENDIF}
+
+{$IFDEF Unix}
+{$IFDEF FPC}
+function _putenv( const variable : Pchar ): integer;
+cdecl; external 'libc.so' name 'putenv';
+{$ENDIF}
+{$ENDIF}
+
+{ Put a variable of the form "name=value" into the environment }
+//function SDL_putenv(const variable: PChar): integer; cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_Init'{$ELSE} SDLLibName{$ENDIF __GPC__}SDLLibName name '';
+function SDL_putenv(const variable: PChar): integer;
+{$EXTERNALSYM SDL_putenv}
+
+// The following function has been commented out to encourage developers to use
+// SDL_putenv as it it more portable
+//function putenv(const variable: PChar): integer;
+//{$EXTERNALSYM putenv}
+
+{$IFDEF WINDOWS}
+{$IFNDEF __GPC__}
+function getenv( const name : Pchar ): PChar; cdecl;
+{$ENDIF}
+{$ENDIF}
+
+{* Retrieve a variable named "name" from the environment }
+//function SDL_getenv(const name: PChar): PChar; cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_Init'{$ELSE} SDLLibName{$ENDIF __GPC__}SDLLibName name '';
+function SDL_getenv(const name: PChar): PChar;
+{$EXTERNALSYM SDL_getenv}
+
+// The following function has been commented out to encourage developers to use
+// SDL_getenv as it it more portable
+//function getenv(const name: PChar): PChar;
+//{$EXTERNALSYM getenv}
+
+{*
+ * This function gives you custom hooks into the window manager information.
+ * It fills the structure pointed to by 'info' with custom information and
+ * returns 1 if the function is implemented. If it's not implemented, or
+ * the version member of the 'info' structure is invalid, it returns 0.
+ *}
+function SDL_GetWMInfo(info : PSDL_SysWMinfo) : integer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_GetWMInfo'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_GetWMInfo}
+
+{------------------------------------------------------------------------------}
+
+//SDL_loadso.h
+{* This function dynamically loads a shared object and returns a pointer
+ * to the object handle (or NULL if there was an error).
+ * The 'sofile' parameter is a system dependent name of the object file.
+ *}
+function SDL_LoadObject( const sofile : PChar ) : Pointer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_LoadObject'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_LoadObject}
+
+{* Given an object handle, this function looks up the address of the
+ * named function in the shared object and returns it. This address
+ * is no longer valid after calling SDL_UnloadObject().
+ *}
+function SDL_LoadFunction( handle : Pointer; const name : PChar ) : Pointer;
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_LoadFunction'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_LoadFunction}
+
+{* Unload a shared object from memory *}
+procedure SDL_UnloadObject( handle : Pointer );
+cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_UnloadObject'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
+{$EXTERNALSYM SDL_UnloadObject}
+
+
+
+{------------------------------------------------------------------------------}
+
+function SDL_Swap32(D: Uint32): Uint32;
+{$EXTERNALSYM SDL_Swap32}
+
+{$ENDIF MORPHOS}
+
+{ FreeAndNil frees the given TObject instance and sets the variable reference
+ to nil. Be careful to only pass TObjects to this routine. }
+procedure FreeAndNil(var Obj);
+
+{ Exit procedure handling }
+
+{ AddExitProc adds the given procedure to the run-time library's exit
+ procedure list. When an application terminates, its exit procedures are
+ executed in reverse order of definition, i.e. the last procedure passed
+ to AddExitProc is the first one to get executed upon termination. }
+procedure AddExitProc(Proc: TProcedure);
+
+// Bitwise Checking functions
+function IsBitOn( value : integer; bit : Byte ) : boolean;
+
+function TurnBitOn( value : integer; bit : Byte ) : integer;
+
+function TurnBitOff( value : integer; bit : Byte ) : integer;
+
+implementation
+
+{$IFDEF __GPC__}
+ {$L 'sdl'} { link sdl.dll.a or libsdl.so or libsdl.a }
+{$ENDIF}
+
+function SDL_TABLESIZE(table: PChar): Integer;
+begin
+ Result := SizeOf(table) div SizeOf(table[0]);
+end;
+
+procedure SDL_OutOfMemory;
+begin
+ {$IFNDEF WINDOWS}
+ SDL_Error(SDL_ENOMEM);
+ {$ENDIF}
+end;
+
+function SDL_RWSeek(context: PSDL_RWops; offset: Integer; whence: Integer) : Integer;
+begin
+ Result := context^.seek(context, offset, whence);
+end;
+
+function SDL_RWTell(context: PSDL_RWops): Integer;
+begin
+ Result := context^.seek(context, 0, 1);
+end;
+
+function SDL_RWRead(context: PSDL_RWops; ptr: Pointer; size: Integer; n: Integer): Integer;
+begin
+ Result := context^.read(context, ptr, size, n);
+end;
+
+function SDL_RWWrite(context: PSDL_RWops; ptr: Pointer; size: Integer; n: Integer): Integer;
+begin
+ Result := context^.write(context, ptr, size, n);
+end;
+
+function SDL_RWClose(context: PSDL_RWops): Integer;
+begin
+ Result := context^.close(context);
+end;
+
+function SDL_LoadWAV(filename: PChar; spec: PSDL_AudioSpec; audio_buf: PUInt8; audiolen: PUInt32): PSDL_AudioSpec;
+begin
+ Result := SDL_LoadWAV_RW(SDL_RWFromFile(filename, 'rb'), 1, spec, audio_buf, audiolen);
+end;
+
+function SDL_CDInDrive( status : TSDL_CDStatus ): LongBool;
+begin
+ Result := ord( status ) > ord( CD_ERROR );
+end;
+
+procedure FRAMES_TO_MSF(frames: Integer; var M: Integer; var S: Integer; var
+ F: Integer);
+var
+ value: Integer;
+begin
+ value := frames;
+ F := value mod CD_FPS;
+ value := value div CD_FPS;
+ S := value mod 60;
+ value := value div 60;
+ M := value;
+end;
+
+function MSF_TO_FRAMES(M: Integer; S: Integer; F: Integer): Integer;
+begin
+ Result := M * 60 * CD_FPS + S * CD_FPS + F;
+end;
+
+procedure SDL_VERSION(var X: TSDL_Version);
+begin
+ X.major := SDL_MAJOR_VERSION;
+ X.minor := SDL_MINOR_VERSION;
+ X.patch := SDL_PATCHLEVEL;
+end;
+
+function SDL_VERSIONNUM(X, Y, Z: Integer): Integer;
+begin
+ Result := X * 1000 + Y * 100 + Z;
+end;
+
+function SDL_COMPILEDVERSION: Integer;
+begin
+ Result := SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL
+ );
+end;
+
+function SDL_VERSION_ATLEAST(X, Y, Z: Integer): LongBool;
+begin
+ Result := (SDL_COMPILEDVERSION >= SDL_VERSIONNUM(X, Y, Z));
+end;
+
+function SDL_LoadBMP(filename: PChar): PSDL_Surface;
+begin
+ Result := SDL_LoadBMP_RW(SDL_RWFromFile(filename, 'rb'), 1);
+end;
+
+function SDL_SaveBMP(surface: PSDL_Surface; filename: PChar): Integer;
+begin
+ Result := SDL_SaveBMP_RW(surface, SDL_RWFromFile(filename, 'wb'), 1);
+end;
+
+function SDL_BlitSurface(src: PSDL_Surface; srcrect: PSDL_Rect; dst:
+ PSDL_Surface;
+ dstrect: PSDL_Rect): Integer;
+begin
+ Result := SDL_UpperBlit(src, srcrect, dst, dstrect);
+end;
+
+function SDL_AllocSurface(flags: UInt32; width, height, depth: Integer;
+ RMask, GMask, BMask, AMask: UInt32): PSDL_Surface;
+begin
+ Result := SDL_CreateRGBSurface(flags, width, height, depth, RMask, GMask,
+ BMask, AMask);
+end;
+
+function SDL_MustLock(Surface: PSDL_Surface): Boolean;
+begin
+ Result := ( ( surface^.offset <> 0 ) or
+ ( ( surface^.flags and ( SDL_HWSURFACE or SDL_ASYNCBLIT or SDL_RLEACCEL ) ) <> 0 ) );
+end;
+
+function SDL_LockMutex(mutex: PSDL_mutex): Integer;
+begin
+ Result := SDL_mutexP(mutex);
+end;
+
+function SDL_UnlockMutex(mutex: PSDL_mutex): Integer;
+begin
+ Result := SDL_mutexV(mutex);
+end;
+
+{$IFDEF WINDOWS}
+function _putenv( const variable : Pchar ): Integer;
+cdecl; external {$IFDEF __GPC__}name '_putenv'{$ELSE} 'MSVCRT.DLL'{$ENDIF __GPC__};
+{$ENDIF}
+
+
+function SDL_putenv(const variable: PChar): Integer;
+begin
+ {$IFDEF WINDOWS}
+ Result := _putenv(variable);
+ {$ENDIF}
+
+ {$IFDEF UNIX}
+ {$IFDEF FPC}
+ Result := _putenv(variable);
+ {$ELSE}
+ Result := libc.putenv(variable);
+ {$ENDIF}
+ {$ENDIF}
+end;
+
+{$IFDEF WINDOWS}
+{$IFNDEF __GPC__}
+function getenv( const name : Pchar ): PChar;
+cdecl; external {$IFDEF __GPC__}name 'getenv'{$ELSE} 'MSVCRT.DLL'{$ENDIF};
+{$ENDIF}
+{$ENDIF}
+
+function SDL_getenv(const name: PChar): PChar;
+begin
+ {$IFDEF WINDOWS}
+
+ {$IFDEF __GPC__}
+ Result := getenv( string( name ) );
+ {$ELSE}
+ Result := getenv( name );
+ {$ENDIF}
+
+ {$ELSE}
+
+ {$IFDEF UNIX}
+
+ {$IFDEF FPC}
+ Result := fpgetenv(name);
+ {$ELSE}
+ Result := libc.getenv(name);
+ {$ENDIF}
+
+ {$ENDIF}
+
+ {$ENDIF}
+end;
+
+function SDL_BUTTON( Button : Integer ) : Integer;
+begin
+ Result := SDL_PRESSED shl ( Button - 1 );
+end;
+
+function SDL_Swap32(D: Uint32): Uint32;
+begin
+ Result := ((D shl 24) or ((D shl 8) and $00FF0000) or ((D shr 8) and $0000FF00) or (D shr 24));
+end;
+
+procedure FreeAndNil(var Obj);
+{$IFNDEF __GPC__}
+{$IFNDEF __TMT__}
+var
+ Temp: TObject;
+{$ENDIF}
+{$ENDIF}
+begin
+{$IFNDEF __GPC__}
+{$IFNDEF __TMT__}
+ Temp := TObject(Obj);
+ Pointer(Obj) := nil;
+ Temp.Free;
+{$ENDIF}
+{$ENDIF}
+end;
+
+{ Exit procedure handling }
+type
+ PExitProcInfo = ^TExitProcInfo;
+ TExitProcInfo = record
+ Next: PExitProcInfo;
+ SaveExit: Pointer;
+ Proc: TProcedure;
+ end;
+
+var
+ ExitProcList: PExitProcInfo = nil;
+
+procedure DoExitProc;
+var
+ P: PExitProcInfo;
+ Proc: TProcedure;
+begin
+ P := ExitProcList;
+ ExitProcList := P^.Next;
+ ExitProc := P^.SaveExit;
+ Proc := P^.Proc;
+ Dispose(P);
+ Proc;
+end;
+
+procedure AddExitProc(Proc: TProcedure);
+var
+ P: PExitProcInfo;
+begin
+ New(P);
+ P^.Next := ExitProcList;
+ P^.SaveExit := ExitProc;
+ P^.Proc := Proc;
+ ExitProcList := P;
+ ExitProc := @DoExitProc;
+end;
+
+function IsBitOn( value : integer; bit : Byte ) : boolean;
+begin
+ result := ( ( value and ( 1 shl bit ) ) <> 0 );
+end;
+
+function TurnBitOn( value : integer; bit : Byte ) : integer;
+begin
+ result := ( value or ( 1 shl bit ) );
+end;
+
+function TurnBitOff( value : integer; bit : Byte ) : integer;
+begin
+ result := ( value and not ( 1 shl bit ) );
+end;
+
+end.
+
+
diff --git a/packages/sdl/src/sdl_gfx.pas b/packages/sdl/src/sdl_gfx.pas
new file mode 100644
index 0000000000..996ec4d4d2
--- /dev/null
+++ b/packages/sdl/src/sdl_gfx.pas
@@ -0,0 +1,691 @@
+unit sdl_gfx;
+{
+ $Id: sdl_gfx.pas,v 1.3 2007/05/29 21:31:04 savage Exp $
+
+}
+{
+ $Log: sdl_gfx.pas,v $
+ Revision 1.3 2007/05/29 21:31:04 savage
+ Changes as suggested by Almindor for 64bit compatibility.
+
+ Revision 1.2 2007/05/20 20:30:18 savage
+ Initial Changes to Handle 64 Bits
+
+ Revision 1.1 2005/01/03 19:08:32 savage
+ Header for the SDL_Gfx library.
+
+
+
+}
+
+{$I jedi-sdl.inc}
+
+interface
+
+uses
+ sdl;
+
+const
+{$IFDEF WINDOWS}
+ SDLgfxLibName = 'SDL_gfx.dll';
+{$ENDIF}
+
+{$IFDEF UNIX}
+{$IFDEF DARWIN}
+ SDLgfxLibName = 'libSDL_gfx.dylib';
+{$ELSE}
+ SDLgfxLibName = 'libSDL_gfx.so';
+{$ENDIF}
+{$ENDIF}
+
+{$IFDEF MACOS}
+ SDLgfxLibName = 'SDL_gfx';
+{$ENDIF}
+
+ // Some rates in Hz
+ FPS_UPPER_LIMIT = 200;
+ FPS_LOWER_LIMIT = 1;
+ FPS_DEFAULT = 30;
+
+// ---- Defines
+
+ SMOOTHING_OFF = 0;
+ SMOOTHING_ON = 1;
+
+
+
+type
+ PFPSmanager = ^TFPSmanager;
+ TFPSmanager = packed record
+ framecount : Uint32;
+ rateticks : single;
+ lastticks : Uint32;
+ rate : Uint32;
+ end;
+
+// ---- Structures
+ PColorRGBA = ^TColorRGBA;
+ TColorRGBA = packed record
+ r : Uint8;
+ g : Uint8;
+ b : Uint8;
+ a : Uint8;
+ end;
+
+ PColorY = ^TColorY;
+ TColorY = packed record
+ y : Uint8;
+ end;
+
+{
+
+ SDL_framerate: framerate manager
+
+ LGPL (c) A. Schiffler
+
+}
+
+procedure SDL_initFramerate( manager : PFPSmanager );
+cdecl; external {$IFDEF __GPC__}name 'SDL_initFramerate'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDL_initFramerate}
+
+function SDL_setFramerate( manager : PFPSmanager; rate : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'SDL_setFramerate'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDL_setFramerate}
+
+function SDL_getFramerate( manager : PFPSmanager ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'SDL_getFramerate'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDL_getFramerate}
+
+procedure SDL_framerateDelay( manager : PFPSmanager );
+cdecl; external {$IFDEF __GPC__}name 'SDL_framerateDelay'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDL_framerateDelay}
+
+{
+
+ SDL_gfxPrimitives: graphics primitives for SDL
+
+ LGPL (c) A. Schiffler
+
+}
+
+// Note: all ___Color routines expect the color to be in format 0xRRGGBBAA
+
+// Pixel
+
+function pixelColor( dst : PSDL_Surface; x : Sint16; y : Sint16; color : Uint32 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'pixelColor'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM pixelColor}
+
+function pixelRGBA( dst : PSDL_Surface; x : Sint16; y : Sint16; r : Uint8; g : Uint8; b : Uint8; a : Uint8 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'pixelRGBA'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM pixelRGBA}
+
+// Horizontal line
+
+function hlineColor( dst : PSDL_Surface; x1: Sint16; x2 : Sint16; y : Sint16; color : Uint32 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'hlineColor'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM hlineColor}
+
+function hlineRGBA( dst : PSDL_Surface; x1: Sint16; x2 : Sint16; y : Sint16; r : Uint8; g : Uint8; b : Uint8; a : Uint8 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'hlineRGBA'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM hlineRGBA}
+
+// Vertical line
+
+function vlineColor( dst : PSDL_Surface; x : Sint16; y1 : Sint16; y2 : Sint16; color : Uint32 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'vlineColor'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM vlineColor}
+
+function vlineRGBA( dst : PSDL_Surface; x : Sint16; y1 : Sint16; y2 : Sint16; r : Uint8; g : Uint8; b : Uint8; a : Uint8 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'vlineRGBA'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM vlineRGBA}
+
+// Rectangle
+
+function rectangleColor( dst : PSDL_Surface; x1 : Sint16; y1 : Sint16; x2 : Sint16; y2 : Sint16; color : Uint32 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'rectangleColor'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM rectangleColor}
+
+function rectangleRGBA( dst : PSDL_Surface; x1 : Sint16; y1 : Sint16;
+ x2 : Sint16; y2 : Sint16; r : Uint8; g : Uint8; b : Uint8; a : Uint8 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'rectangleRGBA'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM rectangleRGBA}
+
+// Filled rectangle (Box)
+
+function boxColor( dst : PSDL_Surface; x1 : Sint16; y1 : Sint16; x2 : Sint16; y2 : Sint16; color : Uint32 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'boxColor'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM boxColor}
+
+function boxRGBA( dst : PSDL_Surface; x1 : Sint16; y1 : Sint16; x2 : Sint16;
+ y2 : Sint16; r : Uint8; g : Uint8; b : Uint8; a : Uint8 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'boxRGBA'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM boxRGBA}
+
+// Line
+
+function lineColor( dst : PSDL_Surface; x1 : Sint16; y1 : Sint16; x2 : Sint16; y2 : Sint16; color : Uint32 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'lineColor'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM lineColor}
+
+function lineRGBA( dst : PSDL_Surface; x1 : Sint16; y1 : Sint16;
+ x2 : Sint16; y2 : Sint16; r : Uint8; g : Uint8; b : Uint8; a : Uint8 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'lineRGBA'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM lineRGBA}
+
+// AA Line
+function aalineColor( dst : PSDL_Surface; x1 : Sint16; y1 : Sint16; x2 : Sint16; y2 : Sint16; color : Uint32 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'aalineColor'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM aalineColor}
+
+function aalineRGBA( dst : PSDL_Surface; x1 : Sint16; y1 : Sint16;
+ x2 : Sint16; y2 : Sint16; r : Uint8; g : Uint8; b : Uint8; a : Uint8 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'aalineRGBA'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM aalineRGBA}
+
+// Circle
+
+function circleColor( dst : PSDL_Surface; x : Sint16; y : Sint16; r : Sint16; color : Uint32 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'circleColor'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM circleColor}
+
+function circleRGBA( dst : PSDL_Surface; x : Sint16; y : Sint16; rad : Sint16; r : Uint8; g : Uint8; b : Uint8; a : Uint8 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'circleRGBA'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM circleRGBA}
+
+// AA Circle
+
+function aacircleColor( dst : PSDL_Surface; x : Sint16; y : Sint16; r : Sint16; color : Uint32 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'aacircleColor'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM aacircleColor}
+
+function aacircleRGBA( dst : PSDL_Surface; x : Sint16; y : Sint16;
+ rad : Sint16; r : Uint8; g : Uint8; b : Uint8; a : Uint8 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'aacircleRGBA'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM aacircleRGBA}
+
+// Filled Circle
+
+function filledCircleColor( dst : PSDL_Surface; x : Sint16; y : Sint16; r : Sint16; color : Uint32 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'filledCircleColor'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM filledCircleColor}
+
+function filledCircleRGBA( dst : PSDL_Surface; x : Sint16; y : Sint16;
+ rad : Sint16; r : Uint8; g : Uint8; b : Uint8; a : Uint8 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'filledCircleRGBA'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM filledCircleRGBA}
+
+// Ellipse
+
+function ellipseColor( dst : PSDL_Surface; x : Sint16; y : Sint16; rx : Sint16; ry : Sint16; color : Uint32 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'ellipseColor'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM ellipseColor}
+
+function ellipseRGBA( dst : PSDL_Surface; x : Sint16; y : Sint16;
+ rx : Sint16; ry : Sint16; r : Uint8; g : Uint8; b : Uint8; a : Uint8 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'ellipseRGBA'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM ellipseRGBA}
+
+// AA Ellipse
+
+function aaellipseColor( dst : PSDL_Surface; xc : Sint16; yc : Sint16; rx : Sint16; ry : Sint16; color : Uint32 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'aaellipseColor'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM aaellipseColor}
+
+function aaellipseRGBA( dst : PSDL_Surface; x : Sint16; y : Sint16;
+ rx : Sint16; ry : Sint16; r : Uint8; g : Uint8; b : Uint8; a : Uint8 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'aaellipseRGBA'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM aaellipseRGBA}
+
+// Filled Ellipse
+
+function filledEllipseColor( dst : PSDL_Surface; x : Sint16; y : Sint16; rx : Sint16; ry : Sint16; color : Uint32 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'filledEllipseColor'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM filledEllipseColor}
+
+function filledEllipseRGBA( dst : PSDL_Surface; x : Sint16; y : Sint16;
+ rx : Sint16; ry : Sint16; r : Uint8; g : Uint8; b : Uint8; a : Uint8 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'filledEllipseRGBA'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM filledEllipseRGBA}
+
+// Pie
+
+function pieColor( dst : PSDL_Surface; x : Sint16; y : Sint16; rad : Sint16;
+ start : Sint16; finish : Sint16; color : Uint32 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'pieColor'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM pieColor}
+
+function pieRGBA( dst : PSDL_Surface; x : Sint16; y : Sint16; rad : Sint16;
+ start : Sint16; finish : Sint16; r : Uint8; g : Uint8; b : Uint8; a : Uint8 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'pieRGBA'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM pieRGBA}
+
+// Filled Pie
+
+function filledPieColor( dst : PSDL_Surface; x : Sint16; y : Sint16; rad : Sint16;
+ start : Sint16; finish : Sint16; color : Uint32 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'filledPieColor'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM filledPieColor}
+
+function filledPieRGBA( dst : PSDL_Surface; x : Sint16; y : Sint16; rad : Sint16;
+ start : Sint16; finish : Sint16; r : Uint8; g : Uint8; b : Uint8; a : Uint8 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'filledPieRGBA'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM filledPieRGBA}
+
+// Trigon
+
+function trigonColor( dst : PSDL_Surface; x1 : Sint16; y1 : Sint16; x2 : Sint16; y2 : Sint16; x3 : Sint16; y3 : Sint16; color : Uint32 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'trigonColor'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM trigonColor}
+
+function trigonRGBA( dst : PSDL_Surface; x1 : Sint16; y1 : Sint16; x2 : Sint16; y2 : Sint16; x3 : Sint16; y3 : Sint16;
+ r : Uint8; g : Uint8; b : Uint8; a : Uint8 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'trigonRGBA'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM trigonRGBA}
+
+// AA-Trigon
+
+function aatrigonColor( dst : PSDL_Surface; x1 : Sint16; y1 : Sint16; x2 : Sint16; y2 : Sint16; x3 : Sint16; y3 : Sint16; color : Uint32 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'aatrigonColor'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM aatrigonColor}
+function aatrigonRGBA( dst : PSDL_Surface; x1 : Sint16; y1 : Sint16; x2 : Sint16; y2 : Sint16; x3 : Sint16; y3 : Sint16;
+ r : Uint8; g : Uint8; b : Uint8; a : Uint8 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'aatrigonRGBA'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM aatrigonRGBA}
+
+// Filled Trigon
+
+function filledTrigonColor( dst : PSDL_Surface; x1 : Sint16; y1 : Sint16; x2 : Sint16; y2 : Sint16; x3 : Sint16; y3 : Sint16; color : Uint32 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'filledTrigonColor'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM filledTrigonColor}
+
+function filledTrigonRGBA( dst : PSDL_Surface; x1 : Sint16; y1 : Sint16; x2 : Sint16; y2 : Sint16; x3 : Sint16; y3 : Sint16;
+ r : Uint8; g : Uint8; b : Uint8; a : Uint8 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'filledTrigonRGBA'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM filledTrigonRGBA}
+
+// Polygon
+
+function polygonColor( dst : PSDL_Surface; const vx : PSint16; const vy : PSint16; n : integer; color : Uint32 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'polygonColor'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM polygonColor}
+
+function polygonRGBA( dst : PSDL_Surface; const vx : PSint16; const vy : PSint16;
+ n : integer; r : Uint8; g : Uint8; b : Uint8; a : Uint8 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'polygonRGBA'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM polygonRGBA}
+
+// AA-Polygon
+
+function aapolygonColor( dst : PSDL_Surface; const vx : PSint16; const vy : PSint16; n : integer; color : Uint32 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'aapolygonColor'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM aapolygonColor}
+
+function aapolygonRGBA( dst : PSDL_Surface; const vx : PSint16; const vy : PSint16;
+ n : integer; r : Uint8; g : Uint8; b : Uint8; a : Uint8 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'aapolygonRGBA'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM aapolygonRGBA}
+
+// Filled Polygon
+
+function filledPolygonColor( dst : PSDL_Surface; const vx : PSint16; const vy : PSint16; n : integer; color : Uint32 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'filledPolygonColor'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM filledPolygonColor}
+
+function filledPolygonRGBA( dst : PSDL_Surface; const vx : PSint16;
+ const vy : PSint16; n : integer; r : Uint8; g : Uint8; b : Uint8; a : Uint8 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'filledPolygonRGBA'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM filledPolygonRGBA}
+
+// Bezier
+// s = number of steps
+
+function bezierColor( dst : PSDL_Surface; const vx : PSint16; const vy : PSint16; n : integer; s : integer; color : Uint32 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'bezierColor'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM bezierColor}
+
+function bezierRGBA( dst : PSDL_Surface; const vx : PSint16; const vy : PSint16;
+ n : integer; s : integer; r : Uint8; g : Uint8; b : Uint8; a : Uint8 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'bezierRGBA'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM bezierRGBA}
+
+
+// Characters/Strings
+
+function characterColor( dst : PSDL_Surface; x : Sint16; y : Sint16; c : char; color : Uint32 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'characterColor'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM characterColor}
+
+function characterRGBA( dst : PSDL_Surface; x : Sint16; y : Sint16; c : char; r : Uint8; g : Uint8; b : Uint8; a : Uint8 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'characterRGBA'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM characterRGBA}
+
+function stringColor( dst : PSDL_Surface; x : Sint16; y : Sint16; const c : PChar; color : Uint32 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'stringColor'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM stringColor}
+
+function stringRGBA( dst : PSDL_Surface; x : Sint16; y : Sint16; const c : PChar; r : Uint8; g : Uint8; b : Uint8; a : Uint8 ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'stringRGBA'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM stringRGBA}
+
+procedure gfxPrimitivesSetFont(const fontdata : Pointer; cw : integer; ch : integer );
+cdecl; external {$IFDEF __GPC__}name 'gfxPrimitivesSetFont'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM gfxPrimitivesSetFont}
+
+{
+
+ SDL_imageFilter - bytes-image "filter" routines
+ (uses inline x86 MMX optimizations if available)
+
+ LGPL (c) A. Schiffler
+
+}
+
+{ Comments: }
+{ 1.) MMX functions work best if all data blocks are aligned on a 32 bytes boundary. }
+{ 2.) Data that is not within an 8 byte boundary is processed using the C routine. }
+{ 3.) Convolution routines do not have C routines at this time. }
+
+// Detect MMX capability in CPU
+function SDL_imageFilterMMXdetect : integer;
+cdecl; external {$IFDEF __GPC__}name 'SDL_imageFilterMMXdetect'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDL_imageFilterMMXdetect}
+
+// Force use of MMX off (or turn possible use back on)
+procedure SDL_imageFilterMMXoff;
+cdecl; external {$IFDEF __GPC__}name 'SDL_imageFilterMMXoff'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDL_imageFilterMMXoff}
+
+procedure SDL_imageFilterMMXon;
+cdecl; external {$IFDEF __GPC__}name 'SDL_imageFilterMMXon'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDL_imageFilterMMXon}
+
+//
+// All routines return:
+// 0 OK
+// -1 Error (internal error, parameter error)
+//
+
+// SDL_imageFilterAdd: D = saturation255(S1 + S2)
+function SDL_imageFilterAdd(Src1 : PChar; Src2 : PChar; Dest : PChar; length : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'SDL_imaSDL_imageFilterAddgeFilterMMXon'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDL_imageFilterAdd}
+
+// SDL_imageFilterMean: D = S1/2 + S2/2
+function SDL_imageFilterMean(Src1 : PChar; Src2 : PChar; Dest : PChar; length : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'SDL_imageFilterMean'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDL_imageFilterMean}
+
+// SDL_imageFilterSub: D = saturation0(S1 - S2)
+function SDL_imageFilterSub(Src1 : PChar; Src2 : PChar; Dest : PChar; length : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'SDL_imageFilterSub'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDL_imageFilterSub}
+
+// SDL_imageFilterAbsDiff: D = | S1 - S2 |
+function SDL_imageFilterAbsDiff(Src1 : PChar; Src2 : PChar; Dest : PChar; length : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'SDL_imageFilterAbsDiff'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDL_imageFilterAbsDiff}
+
+// SDL_imageFilterMult: D = saturation(S1 * S2)
+function SDL_imageFilterMult(Src1 : PChar; Src2 : PChar; Dest : PChar; length : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'SDL_imageFilterMult'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDL_imageFilterMult}
+
+// SDL_imageFilterMultNor: D = S1 * S2 (non-MMX)
+function SDL_imageFilterMultNor(Src1 : PChar; Src2 : PChar; Dest : PChar; length : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'SDL_imageFilterMultNor'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDL_imageFilterMultNor}
+
+// SDL_imageFilterMultDivby2: D = saturation255(S1/2 * S2)
+function SDL_imageFilterMultDivby2(Src1 : PChar; Src2 : PChar; Dest : PChar;
+ length : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'SDL_imageFilterMultDivby2'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDL_imageFilterMultDivby2}
+
+// SDL_imageFilterMultDivby4: D = saturation255(S1/2 * S2/2)
+function SDL_imageFilterMultDivby4(Src1 : PChar; Src2 : PChar; Dest : PChar;
+ length : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'SDL_imageFilterMultDivby4'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDL_imageFilterMultDivby4}
+
+// SDL_imageFilterBitAnd: D = S1 & S2
+function SDL_imageFilterBitAnd(Src1 : PChar; Src2 : PChar; Dest : PChar; length : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'SDL_imageFilterBitAnd'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDL_imageFilterBitAnd}
+
+// SDL_imageFilterBitOr: D = S1 | S2
+function SDL_imageFilterBitOr(Src1 : PChar; Src2 : PChar; Dest : PChar; length : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'SDL_imageFilterBitOr'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDL_imageFilterBitOr}
+
+// SDL_imageFilterDiv: D = S1 / S2 (non-MMX)
+function SDL_imageFilterDiv(Src1 : PChar; Src2 : PChar; Dest : PChar; length : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'SDL_imageFilterDiv'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDL_imageFilterDiv}
+
+// SDL_imageFilterBitNegation: D = !S
+function SDL_imageFilterBitNegation(Src1 : PChar; Dest : PChar; length : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'SDL_imageFilterBitNegation'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDL_imageFilterBitNegation}
+
+// SDL_imageFilterAddByte: D = saturation255(S + C)
+function SDL_imageFilterAddByte(Src1 : PChar; Dest : PChar; length : integer; C : char ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'SDL_imageFilterAddByte'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDL_imageFilterAddByte}
+
+// SDL_imageFilterAddUint: D = saturation255(S + (uint)C)
+function SDL_imageFilterAddUint(Src1 : PChar; Dest : PChar; length : integer; C : Cardinal ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'SDL_imageFilterAddUint'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDL_imageFilterAddUint}
+
+// SDL_imageFilterAddByteToHalf: D = saturation255(S/2 + C)
+function SDL_imageFilterAddByteToHalf(Src1 : PChar; Dest : PChar; length : integer;
+ C : char ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'SDL_imageFilterAddByteToHalf'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDL_imageFilterAddByteToHalf}
+
+// SDL_imageFilterSubByte: D = saturation0(S - C)
+function SDL_imageFilterSubByte(Src1 : PChar; Dest : PChar; length : integer; C : char ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'SDL_imageFilterSubByte'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDL_imageFilterSubByte}
+
+// SDL_imageFilterSubUint: D = saturation0(S - (uint)C)
+function SDL_imageFilterSubUint(Src1 : PChar; Dest : PChar; length : integer; C : Cardinal ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'SDL_imageFilterSubUint'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDL_imageFilterSubUint}
+
+// SDL_imageFilterShiftRight: D = saturation0(S >> N)
+function SDL_imageFilterShiftRight(Src1 : PChar; Dest : PChar; length : integer; N : char ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'SDL_imageFilterShiftRight'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDL_imageFilterShiftRight}
+
+// SDL_imageFilterShiftRightUint: D = saturation0((uint)S >> N)
+function SDL_imageFilterShiftRightUint(Src1 : PChar; Dest : PChar; length : integer; N : char ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'SDL_imageFilterShiftRightUint'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDL_imageFilterShiftRightUint}
+
+// SDL_imageFilterMultByByte: D = saturation255(S * C)
+function SDL_imageFilterMultByByte(Src1 : PChar; Dest : PChar; length : integer; C : char ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'SDL_imageFilterMultByByte'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDL_imageFilterMultByByte}
+
+// SDL_imageFilterShiftRightAndMultByByte: D = saturation255((S >> N) * C)
+function SDL_imageFilterShiftRightAndMultByByte(Src1 : PChar; Dest : PChar; length : integer;
+ N : char; C : char ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'SDL_imageFilterShiftRightAndMultByByte'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDL_imageFilterShiftRightAndMultByByte}
+
+// SDL_imageFilterShiftLeftByte: D = (S << N)
+function SDL_imageFilterShiftLeftByte(Src1 : PChar; Dest : PChar; length : integer;
+ N : char ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'SDL_imageFilterShiftLeftByte'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDL_imageFilterShiftLeftByte}
+
+// SDL_imageFilterShiftLeftUint: D = ((uint)S << N)
+function SDL_imageFilterShiftLeftUint(Src1 : PChar; Dest : PChar; length : integer;
+ N : char ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'SDL_imageFilterShiftLeftUint'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDL_imageFilterShiftLeftUint}
+
+// SDL_imageFilterShiftLeft: D = saturation255(S << N)
+function SDL_imageFilterShiftLeft(Src1 : PChar; Dest : PChar; length : integer; N : char ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'SDL_imageFilterShiftLeft'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDL_imageFilterShiftLeft}
+
+// SDL_imageFilterBinarizeUsingThreshold: D = S >= T ? 255:0
+function SDL_imageFilterBinarizeUsingThreshold(Src1 : PChar; Dest : PChar; length : integer;
+ T : char ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'SDL_imageFilterBinarizeUsingThreshold'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDL_imageFilterBinarizeUsingThreshold}
+
+// SDL_imageFilterClipToRange: D = (S >= Tmin) & (S <= Tmax) 255:0
+function SDL_imageFilterClipToRange(Src1 : PChar; Dest : PChar; length : integer;
+ Tmin : Byte; Tmax : Byte ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'SDL_imageFilterClipToRange'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDL_imageFilterClipToRange}
+
+// SDL_imageFilterNormalizeLinear: D = saturation255((Nmax - Nmin)/(Cmax - Cmin)*(S - Cmin) + Nmin)
+function SDL_imageFilterNormalizeLinear(Src1 : PChar; Dest : PChar; length : integer; Cmin : integer;
+ Cmax : integer; Nmin : integer; Nmax : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'SDL_imageFilterClipToRange'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDL_imageFilterClipToRange}
+
+{ !!! NO C-ROUTINE FOR THESE FUNCTIONS YET !!! }
+
+// SDL_imageFilterConvolveKernel3x3Divide: Dij = saturation0and255( ... )
+function SDL_imageFilterConvolveKernel3x3Divide(Src : PChar; Dest : PChar; rows : integer;
+ columns : integer; Kernel : PShortInt; Divisor : Byte ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'SDL_imageFilterConvolveKernel3x3Divide'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDL_imageFilterConvolveKernel3x3Divide}
+
+// SDL_imageFilterConvolveKernel5x5Divide: Dij = saturation0and255( ... )
+function SDL_imageFilterConvolveKernel5x5Divide(Src : PChar; Dest : PChar; rows : integer;
+ columns : integer; Kernel : PShortInt; Divisor : Byte ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'SDL_imageFilterConvolveKernel5x5Divide'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDL_imageFilterConvolveKernel5x5Divide}
+
+// SDL_imageFilterConvolveKernel7x7Divide: Dij = saturation0and255( ... )
+function SDL_imageFilterConvolveKernel7x7Divide(Src : PChar; Dest : PChar; rows : integer;
+ columns : integer; Kernel : PShortInt; Divisor : Byte ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'SDL_imageFilterConvolveKernel7x7Divide'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDL_imageFilterConvolveKernel7x7Divide}
+
+// SDL_imageFilterConvolveKernel9x9Divide: Dij = saturation0and255( ... )
+function SDL_imageFilterConvolveKernel9x9Divide(Src : PChar; Dest : PChar; rows : integer;
+ columns : integer; Kernel : PShortInt; Divisor : Byte ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'SDL_imageFilterConvolveKernel9x9Divide'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDL_imageFilterConvolveKernel9x9Divide}
+
+// SDL_imageFilterConvolveKernel3x3ShiftRight: Dij = saturation0and255( ... )
+function SDL_imageFilterConvolveKernel3x3ShiftRight(Src : PChar; Dest : PChar; rows : integer;
+ columns : integer; Kernel : PShortInt;
+ NRightShift : char ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'SDL_imageFilterConvolveKernel3x3ShiftRight'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDL_imageFilterConvolveKernel3x3ShiftRight}
+
+// SDL_imageFilterConvolveKernel5x5ShiftRight: Dij = saturation0and255( ... )
+function SDL_imageFilterConvolveKernel5x5ShiftRight(Src : PChar; Dest : PChar; rows : integer;
+ columns : integer; Kernel : PShortInt;
+ NRightShift : char ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'SDL_imageFilterConvolveKernel5x5ShiftRight'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDL_imageFilterConvolveKernel5x5ShiftRight}
+
+// SDL_imageFilterConvolveKernel7x7ShiftRight: Dij = saturation0and255( ... )
+function SDL_imageFilterConvolveKernel7x7ShiftRight(Src : PChar; Dest : PChar; rows : integer;
+ columns : integer; Kernel : PShortInt;
+ NRightShift : char ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'SDL_imageFilterConvolveKernel7x7ShiftRight'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDL_imageFilterConvolveKernel7x7ShiftRight}
+
+// SDL_imageFilterConvolveKernel9x9ShiftRight: Dij = saturation0and255( ... )
+function SDL_imageFilterConvolveKernel9x9ShiftRight(Src : PChar; Dest : PChar; rows : integer;
+ columns : integer; Kernel : PShortInt;
+ NRightShift : char ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'SDL_imageFilterConvolveKernel9x9ShiftRight'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDL_imageFilterConvolveKernel9x9ShiftRight}
+
+// SDL_imageFilterSobelX: Dij = saturation255( ... )
+function SDL_imageFilterSobelX(Src : PChar; Dest : PChar; rows : integer; columns : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'SDL_imageFilterSobelX'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDL_imageFilterSobelX}
+
+// SDL_imageFilterSobelXShiftRight: Dij = saturation255( ... )
+function SDL_imageFilterSobelXShiftRight(Src : PChar; Dest : PChar; rows : integer; columns : integer;
+ NRightShift : char ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'SDL_imageFilterSobelXShiftRight'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDL_imageFilterSobelXShiftRight}
+
+// Align/restore stack to 32 byte boundary -- Functionality untested! --
+procedure SDL_imageFilterAlignStack;
+cdecl; external {$IFDEF __GPC__}name 'SDL_imageFilterAlignStack'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDL_imageFilterAlignStack}
+
+procedure SDL_imageFilterRestoreStack;
+cdecl; external {$IFDEF __GPC__}name 'SDL_imageFilterRestoreStack'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDL_imageFilterRestoreStack}
+
+{
+
+ SDL_rotozoom - rotozoomer
+
+ LGPL (c) A. Schiffler
+
+}
+
+{
+
+ rotozoomSurface()
+
+ Rotates and zoomes a 32bit or 8bit 'src' surface to newly created 'dst' surface.
+ 'angle' is the rotation in degrees. 'zoom' a scaling factor. If 'smooth' is 1
+ then the destination 32bit surface is anti-aliased. If the surface is not 8bit
+ or 32bit RGBA/ABGR it will be converted into a 32bit RGBA format on the fly.
+
+}
+
+function rotozoomSurface( src : PSDL_Surface; angle : double; zoom : double; smooth : integer ) : PSDL_Surface;
+cdecl; external {$IFDEF __GPC__}name 'rotozoomSurface'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM rotozoomSurface}
+
+function rotozoomSurfaceXY( src : PSDL_Surface; angle : double; zoomx : double; zoomy : double; smooth : integer ) : PSDL_Surface;
+cdecl; external {$IFDEF __GPC__}name 'rotozoomSurfaceXY'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM rotozoomSurfaceXY}
+
+{ Returns the size of the target surface for a rotozoomSurface() call }
+
+procedure rotozoomSurfaceSize( width : integer; height : integer; angle : double; zoom : double; var dstwidth : integer;
+ var dstheight : integer );
+cdecl; external {$IFDEF __GPC__}name 'rotozoomSurfaceSize'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM rotozoomSurfaceSize}
+
+procedure rotozoomSurfaceSizeXY
+ ( width : integer; height : integer; angle : double; zoomx : double; zoomy : double;
+ var dstwidth : integer; var dstheight : integer );
+cdecl; external {$IFDEF __GPC__}name 'rotozoomSurfaceSizeXY'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM rotozoomSurfaceSizeXY}
+
+{
+
+ zoomSurface()
+
+ Zoomes a 32bit or 8bit 'src' surface to newly created 'dst' surface.
+ 'zoomx' and 'zoomy' are scaling factors for width and height. If 'smooth' is 1
+ then the destination 32bit surface is anti-aliased. If the surface is not 8bit
+ or 32bit RGBA/ABGR it will be converted into a 32bit RGBA format on the fly.
+
+}
+
+function zoomSurface(src : PSDL_Surface; zoomx : double; zoomy : double; smooth : integer ) : PSDL_Surface;
+cdecl; external {$IFDEF __GPC__}name 'zoomSurface'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM zoomSurface}
+
+{ Returns the size of the target surface for a zoomSurface() call }
+
+procedure zoomSurfaceSize( width : integer; height : integer; zoomx : double; zoomy : double; var dstwidth : integer; var dstheight : integer );
+cdecl; external {$IFDEF __GPC__}name 'zoomSurfaceSize'{$ELSE} SDLgfxLibName{$ENDIF __GPC__};
+{$EXTERNALSYM zoomSurfaceSize}
+
+implementation
+
+end. \ No newline at end of file
diff --git a/packages/sdl/src/sdl_image.pas b/packages/sdl/src/sdl_image.pas
new file mode 100644
index 0000000000..7f0c81af7d
--- /dev/null
+++ b/packages/sdl/src/sdl_image.pas
@@ -0,0 +1,345 @@
+unit sdl_image;
+{
+ $Id: sdl_image.pas,v 1.14 2007/05/29 21:31:13 savage Exp $
+
+}
+{******************************************************************************}
+{ }
+{ Borland Delphi SDL_Image - An example image loading library for use }
+{ with SDL }
+{ Conversion of the Simple DirectMedia Layer Image Headers }
+{ }
+{ Portions created by Sam Lantinga <slouken@devolution.com> are }
+{ Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga }
+{ 5635-34 Springhouse Dr. }
+{ Pleasanton, CA 94588 (USA) }
+{ }
+{ All Rights Reserved. }
+{ }
+{ The original files are : SDL_image.h }
+{ }
+{ The initial developer of this Pascal code was : }
+{ Matthias Thoma <ma.thoma@gmx.de> }
+{ }
+{ Portions created by Matthias Thoma are }
+{ Copyright (C) 2000 - 2001 Matthias Thoma. }
+{ }
+{ }
+{ Contributor(s) }
+{ -------------- }
+{ Dominique Louis <Dominique@SavageSoftware.com.au> }
+{ }
+{ Obtained through: }
+{ Joint Endeavour of Delphi Innovators ( Project JEDI ) }
+{ }
+{ You may retrieve the latest version of this file at the Project }
+{ JEDI home page, located at http://delphi-jedi.org }
+{ }
+{ The contents of this file are used with permission, subject to }
+{ the Mozilla Public License Version 1.1 (the "License"); you may }
+{ not use this file except in compliance with the License. You may }
+{ obtain a copy of the License at }
+{ http://www.mozilla.org/MPL/MPL-1.1.html }
+{ }
+{ Software distributed under the License is distributed on an }
+{ "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or }
+{ implied. See the License for the specific language governing }
+{ rights and limitations under the License. }
+{ }
+{ Description }
+{ ----------- }
+{ A simple library to load images of various formats as SDL surfaces }
+{ }
+{ Requires }
+{ -------- }
+{ SDL.pas in your search path. }
+{ }
+{ Programming Notes }
+{ ----------------- }
+{ See the Aliens Demo on how to make use of this libaray }
+{ }
+{ Revision History }
+{ ---------------- }
+{ April 02 2001 - MT : Initial Translation }
+{ }
+{ May 08 2001 - DL : Added ExternalSym derectives and copyright header }
+{ }
+{ April 03 2003 - DL : Added jedi-sdl.inc include file to support more }
+{ Pascal compilers. Initial support is now included }
+{ for GnuPascal, VirtualPascal, TMT and obviously }
+{ continue support for Delphi Kylix and FreePascal. }
+{ }
+{ April 08 2003 - MK : Aka Mr Kroket - Added Better FPC support }
+{ }
+{ April 24 2003 - DL : under instruction from Alexey Barkovoy, I have added}
+{ better TMT Pascal support and under instruction }
+{ from Prof. Abimbola Olowofoyeku (The African Chief),}
+{ I have added better Gnu Pascal support }
+{ }
+{ April 30 2003 - DL : under instruction from David Mears AKA }
+{ Jason Siletto, I have added FPC Linux support. }
+{ This was compiled with fpc 1.1, so remember to set }
+{ include file path. ie. -Fi/usr/share/fpcsrc/rtl/* }
+{ }
+{
+ $Log: sdl_image.pas,v $
+ Revision 1.14 2007/05/29 21:31:13 savage
+ Changes as suggested by Almindor for 64bit compatibility.
+
+ Revision 1.13 2007/05/20 20:30:54 savage
+ Initial Changes to Handle 64 Bits
+
+ Revision 1.12 2006/12/02 00:14:40 savage
+ Updated to latest version
+
+ Revision 1.11 2005/04/10 18:22:59 savage
+ Changes as suggested by Michalis, thanks.
+
+ Revision 1.10 2005/04/10 11:48:33 savage
+ Changes as suggested by Michalis, thanks.
+
+ Revision 1.9 2005/01/05 01:47:07 savage
+ Changed LibName to reflect what MacOS X should have. ie libSDL*-1.2.0.dylib respectively.
+
+ Revision 1.8 2005/01/04 23:14:44 savage
+ Changed LibName to reflect what most Linux distros will have. ie libSDL*-1.2.so.0 respectively.
+
+ Revision 1.7 2005/01/01 02:03:12 savage
+ Updated to v1.2.4
+
+ Revision 1.6 2004/08/14 22:54:30 savage
+ Updated so that Library name defines are correctly defined for MacOS X.
+
+ Revision 1.5 2004/05/10 14:10:04 savage
+ Initial MacOS X support. Fixed defines for MACOS ( Classic ) and DARWIN ( MacOS X ).
+
+ Revision 1.4 2004/04/13 09:32:08 savage
+ Changed Shared object names back to just the .so extension to avoid conflicts on various Linux/Unix distros. Therefore developers will need to create Symbolic links to the actual Share Objects if necessary.
+
+ Revision 1.3 2004/04/01 20:53:23 savage
+ Changed Linux Shared Object names so they reflect the Symbolic Links that are created when installing the RPMs from the SDL site.
+
+ Revision 1.2 2004/03/30 20:23:28 savage
+ Tidied up use of UNIX compiler directive.
+
+ Revision 1.1 2004/02/14 23:35:42 savage
+ version 1 of sdl_image, sdl_mixer and smpeg.
+
+
+}
+{******************************************************************************}
+
+{$I jedi-sdl.inc}
+
+interface
+
+uses
+{$IFDEF __GPC__}
+ gpc,
+{$ENDIF}
+ sdl;
+
+const
+{$IFDEF WINDOWS}
+ SDL_ImageLibName = 'SDL_Image.dll';
+{$ENDIF}
+
+{$IFDEF UNIX}
+{$IFDEF DARWIN}
+ SDL_ImageLibName = 'libSDL_image-1.2.0.dylib';
+{$ELSE}
+ {$IFDEF FPC}
+ SDL_ImageLibName = 'libSDL_image.so';
+ {$ELSE}
+ SDL_ImageLibName = 'libSDL_image-1.2.so.0';
+ {$ENDIF}
+{$ENDIF}
+{$ENDIF}
+
+{$IFDEF MACOS}
+ SDL_ImageLibName = 'SDL_image';
+{$ENDIF}
+
+ // Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL
+ SDL_IMAGE_MAJOR_VERSION = 1;
+{$EXTERNALSYM SDL_IMAGE_MAJOR_VERSION}
+ SDL_IMAGE_MINOR_VERSION = 2;
+{$EXTERNALSYM SDL_IMAGE_MINOR_VERSION}
+ SDL_IMAGE_PATCHLEVEL = 5;
+{$EXTERNALSYM SDL_IMAGE_PATCHLEVEL}
+
+{ This macro can be used to fill a version structure with the compile-time
+ version of the SDL_image library. }
+procedure SDL_IMAGE_VERSION( var X : TSDL_Version );
+{$EXTERNALSYM SDL_IMAGE_VERSION}
+
+{ This function gets the version of the dynamically linked SDL_image library.
+ it should NOT be used to fill a version structure, instead you should
+ use the SDL_IMAGE_VERSION() macro.
+ }
+function IMG_Linked_Version : PSDL_version;
+external {$IFDEF __GPC__}name 'IMG_Linked_Version'{$ELSE} SDL_ImageLibName{$ENDIF __GPC__};
+{$EXTERNALSYM IMG_Linked_Version}
+
+{ Load an image from an SDL data source.
+ The 'type' may be one of: "BMP", "GIF", "PNG", etc.
+
+ If the image format supports a transparent pixel, SDL will set the
+ colorkey for the surface. You can enable RLE acceleration on the
+ surface afterwards by calling:
+ SDL_SetColorKey(image, SDL_RLEACCEL, image.format.colorkey);
+}
+function IMG_LoadTyped_RW(src: PSDL_RWops; freesrc: Integer; _type: PChar): PSDL_Surface;
+cdecl; external {$IFDEF __GPC__}name 'IMG_LoadTyped_RW'{$ELSE} SDL_ImageLibName{$ENDIF __GPC__};
+{$EXTERNALSYM IMG_LoadTyped_RW}
+{ Convenience functions }
+function IMG_Load(const _file: PChar): PSDL_Surface;
+cdecl; external {$IFDEF __GPC__}name 'IMG_Load'{$ELSE} SDL_ImageLibName{$ENDIF __GPC__};
+{$EXTERNALSYM IMG_Load}
+function IMG_Load_RW(src: PSDL_RWops; freesrc: Integer): PSDL_Surface;
+cdecl; external {$IFDEF __GPC__}name 'IMG_Load_RW'{$ELSE} SDL_ImageLibName{$ENDIF __GPC__};
+{$EXTERNALSYM IMG_Load_RW}
+
+{ Invert the alpha of a surface for use with OpenGL
+ This function is now a no-op, and only provided for backwards compatibility. }
+function IMG_InvertAlpha(_on: Integer): Integer;
+cdecl; external {$IFDEF __GPC__}name 'IMG_InvertAlpha'{$ELSE} SDL_ImageLibName{$ENDIF __GPC__};
+{$EXTERNALSYM IMG_InvertAlpha}
+
+{ Functions to detect a file type, given a seekable source }
+function IMG_isBMP(src: PSDL_RWops): Integer;
+cdecl; external {$IFDEF __GPC__}name 'IMG_isBMP'{$ELSE} SDL_ImageLibName{$ENDIF __GPC__};
+{$EXTERNALSYM IMG_isBMP}
+
+function IMG_isGIF(src: PSDL_RWops): Integer;
+cdecl; external {$IFDEF __GPC__}name 'IMG_isGIF'{$ELSE} SDL_ImageLibName{$ENDIF __GPC__};
+{$EXTERNALSYM IMG_isGIF}
+
+function IMG_isJPG(src: PSDL_RWops): Integer;
+cdecl; external {$IFDEF __GPC__}name 'IMG_isJPG'{$ELSE} SDL_ImageLibName{$ENDIF __GPC__};
+{$EXTERNALSYM IMG_isJPG}
+
+function IMG_isLBM(src: PSDL_RWops): Integer;
+cdecl; external {$IFDEF __GPC__}name 'IMG_isLBM'{$ELSE} SDL_ImageLibName{$ENDIF __GPC__};
+{$EXTERNALSYM IMG_isLBM}
+
+function IMG_isPCX(src: PSDL_RWops): Integer;
+cdecl; external {$IFDEF __GPC__}name 'IMG_isPCX'{$ELSE} SDL_ImageLibName{$ENDIF __GPC__};
+{$EXTERNALSYM IMG_isPCX}
+
+function IMG_isPNG(src: PSDL_RWops): Integer;
+cdecl; external {$IFDEF __GPC__}name 'IMG_isPNG'{$ELSE} SDL_ImageLibName{$ENDIF __GPC__};
+{$EXTERNALSYM IMG_isPNG}
+
+function IMG_isPNM(src: PSDL_RWops): Integer;
+cdecl; external {$IFDEF __GPC__}name 'IMG_isPNM'{$ELSE} SDL_ImageLibName{$ENDIF __GPC__};
+{$EXTERNALSYM IMG_isPNM}
+
+function IMG_isTIF(src: PSDL_RWops): Integer;
+cdecl; external {$IFDEF __GPC__}name 'IMG_isTIF'{$ELSE} SDL_ImageLibName{$ENDIF __GPC__};
+{$EXTERNALSYM IMG_isTIF}
+
+function IMG_isXCF(src: PSDL_RWops): Integer;
+cdecl; external {$IFDEF __GPC__}name 'IMG_isXCF'{$ELSE} SDL_ImageLibName{$ENDIF __GPC__};
+{$EXTERNALSYM IMG_isXCF}
+
+function IMG_isXPM(src: PSDL_RWops): Integer;
+cdecl; external {$IFDEF __GPC__}name 'IMG_isXPM'{$ELSE} SDL_ImageLibName{$ENDIF __GPC__};
+{$EXTERNALSYM IMG_isXPM}
+
+function IMG_isXV(src: PSDL_RWops): Integer;
+cdecl; external {$IFDEF __GPC__}name 'IMG_isXV'{$ELSE} SDL_ImageLibName{$ENDIF __GPC__};
+{$EXTERNALSYM IMG_isXV}
+
+
+{ Individual loading functions }
+function IMG_LoadBMP_RW(src: PSDL_RWops): PSDL_Surface;
+cdecl; external {$IFDEF __GPC__}name 'IMG_LoadBMP_RW'{$ELSE} SDL_ImageLibName{$ENDIF __GPC__};
+{$EXTERNALSYM IMG_LoadBMP_RW}
+
+function IMG_LoadGIF_RW(src: PSDL_RWops): PSDL_Surface;
+cdecl; external {$IFDEF __GPC__}name 'IMG_LoadGIF_RW'{$ELSE} SDL_ImageLibName{$ENDIF __GPC__};
+{$EXTERNALSYM IMG_LoadGIF_RW}
+
+function IMG_LoadJPG_RW(src: PSDL_RWops): PSDL_Surface;
+cdecl; external {$IFDEF __GPC__}name 'IMG_LoadJPG_RW'{$ELSE} SDL_ImageLibName{$ENDIF __GPC__};
+{$EXTERNALSYM IMG_LoadJPG_RW}
+
+function IMG_LoadLBM_RW(src: PSDL_RWops): PSDL_Surface;
+cdecl; external {$IFDEF __GPC__}name 'IMG_LoadLBM_RW'{$ELSE} SDL_ImageLibName{$ENDIF __GPC__};
+{$EXTERNALSYM IMG_LoadLBM_RW}
+
+function IMG_LoadPCX_RW(src: PSDL_RWops): PSDL_Surface;
+cdecl; external {$IFDEF __GPC__}name 'IMG_LoadPCX_RW'{$ELSE} SDL_ImageLibName{$ENDIF __GPC__};
+{$EXTERNALSYM IMG_LoadPCX_RW}
+
+function IMG_LoadPNM_RW(src: PSDL_RWops): PSDL_Surface;
+cdecl; external {$IFDEF __GPC__}name 'IMG_LoadPNM_RW'{$ELSE} SDL_ImageLibName{$ENDIF __GPC__};
+{$EXTERNALSYM IMG_LoadPNM_RW}
+
+function IMG_LoadPNG_RW(src: PSDL_RWops): PSDL_Surface;
+cdecl; external {$IFDEF __GPC__}name 'IMG_LoadPNG_RW'{$ELSE} SDL_ImageLibName{$ENDIF __GPC__};
+{$EXTERNALSYM IMG_LoadPNG_RW}
+
+function IMG_LoadTGA_RW(src: PSDL_RWops): PSDL_Surface;
+cdecl; external {$IFDEF __GPC__}name 'IMG_LoadTGA_RW'{$ELSE} SDL_ImageLibName{$ENDIF __GPC__};
+{$EXTERNALSYM IMG_LoadTGA_RW}
+
+function IMG_LoadTIF_RW(src: PSDL_RWops): PSDL_Surface;
+cdecl; external {$IFDEF __GPC__}name 'IMG_LoadTIF_RW'{$ELSE} SDL_ImageLibName{$ENDIF __GPC__};
+{$EXTERNALSYM IMG_LoadTIF_RW}
+
+function IMG_LoadXCF_RW(src: PSDL_RWops): PSDL_Surface;
+cdecl; external {$IFDEF __GPC__}name 'IMG_LoadXCF_RW'{$ELSE} SDL_ImageLibName{$ENDIF __GPC__};
+{$EXTERNALSYM IMG_LoadXCF_RW}
+
+function IMG_LoadXPM_RW(src: PSDL_RWops): PSDL_Surface;
+cdecl; external {$IFDEF __GPC__}name 'IMG_LoadXPM_RW'{$ELSE} SDL_ImageLibName{$ENDIF __GPC__};
+{$EXTERNALSYM IMG_LoadXPM_RW}
+
+function IMG_LoadXV_RW(src: PSDL_RWops): PSDL_Surface;
+cdecl; external {$IFDEF __GPC__}name 'IMG_LoadXV_RW'{$ELSE} SDL_ImageLibName{$ENDIF __GPC__};
+{$EXTERNALSYM IMG_LoadXV_RW}
+
+function IMG_ReadXPMFromArray( xpm : PPChar ): PSDL_Surface;
+cdecl; external {$IFDEF __GPC__}name 'IMG_ReadXPMFromArray'{$ELSE} SDL_ImageLibName{$ENDIF __GPC__};
+{$EXTERNALSYM IMG_ReadXPMFromArray}
+
+
+
+
+{ used internally, NOT an exported function }
+//function IMG_string_equals( const str1 : PChar; const str2 : PChar ) : integer;
+//cdecl; external {$IFDEF __GPC__}name 'IMG_string_equals'{$ELSE} SDL_ImageLibName{$ENDIF __GPC__};
+//{ $ EXTERNALSYM IMG_string_equals}
+
+{ Error Macros }
+{ We'll use SDL for reporting errors }
+procedure IMG_SetError( fmt : PChar );
+
+function IMG_GetError : PChar;
+
+implementation
+
+{$IFDEF __GPC__}
+ {$L 'sdl_image'} { link sdl_image.dll.a or libsdl_image.so or libsdl_image.a }
+{$ENDIF}
+
+procedure SDL_IMAGE_VERSION( var X : TSDL_Version );
+begin
+ X.major := SDL_IMAGE_MAJOR_VERSION;
+ X.minor := SDL_IMAGE_MINOR_VERSION;
+ X.patch := SDL_IMAGE_PATCHLEVEL;
+end;
+
+procedure IMG_SetError( fmt : PChar );
+begin
+ SDL_SetError( fmt );
+end;
+
+function IMG_GetError : PChar;
+begin
+ result := SDL_GetError;
+end;
+
+end.
diff --git a/packages/sdl/src/sdl_mixer.pas b/packages/sdl/src/sdl_mixer.pas
new file mode 100644
index 0000000000..b6d305db8b
--- /dev/null
+++ b/packages/sdl/src/sdl_mixer.pas
@@ -0,0 +1,1122 @@
+unit sdl_mixer;
+{******************************************************************************}
+{
+ $Id: sdl_mixer.pas,v 1.18 2007/05/29 21:31:44 savage Exp $
+
+}
+{ }
+{ Borland Delphi SDL_Mixer - Simple DirectMedia Layer Mixer Library }
+{ Conversion of the Simple DirectMedia Layer Headers }
+{ }
+{ Portions created by Sam Lantinga <slouken@devolution.com> are }
+{ Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga }
+{ 5635-34 Springhouse Dr. }
+{ Pleasanton, CA 94588 (USA) }
+{ }
+{ All Rights Reserved. }
+{ }
+{ The original files are : SDL_mixer.h }
+{ music_cmd.h }
+{ wavestream.h }
+{ timidity.h }
+{ playmidi.h }
+{ music_ogg.h }
+{ mikmod.h }
+{ }
+{ The initial developer of this Pascal code was : }
+{ Dominqiue Louis <Dominique@SavageSoftware.com.au> }
+{ }
+{ Portions created by Dominqiue Louis are }
+{ Copyright (C) 2000 - 2001 Dominqiue Louis. }
+{ }
+{ }
+{ Contributor(s) }
+{ -------------- }
+{ Matthias Thoma <ma.thoma@gmx.de> }
+{ }
+{ Obtained through: }
+{ Joint Endeavour of Delphi Innovators ( Project JEDI ) }
+{ }
+{ You may retrieve the latest version of this file at the Project }
+{ JEDI home page, located at http://delphi-jedi.org }
+{ }
+{ The contents of this file are used with permission, subject to }
+{ the Mozilla Public License Version 1.1 (the "License"); you may }
+{ not use this file except in compliance with the License. You may }
+{ obtain a copy of the License at }
+{ http://www.mozilla.org/MPL/MPL-1.1.html }
+{ }
+{ Software distributed under the License is distributed on an }
+{ "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or }
+{ implied. See the License for the specific language governing }
+{ rights and limitations under the License. }
+{ }
+{ Description }
+{ ----------- }
+{ }
+{ }
+{ }
+{ }
+{ }
+{ }
+{ }
+{ Requires }
+{ -------- }
+{ SDL.pas & SMPEG.pas somewhere within your search path. }
+{ }
+{ Programming Notes }
+{ ----------------- }
+{ See the Aliens Demo to see how this library is used }
+{ }
+{ Revision History }
+{ ---------------- }
+{ April 02 2001 - DL : Initial Translation }
+{ }
+{ February 02 2002 - DL : Update to version 1.2.1 }
+{ }
+{ April 03 2003 - DL : Added jedi-sdl.inc include file to support more }
+{ Pascal compilers. Initial support is now included }
+{ for GnuPascal, VirtualPascal, TMT and obviously }
+{ continue support for Delphi Kylix and FreePascal. }
+{ }
+{ April 24 2003 - DL : under instruction from Alexey Barkovoy, I have added}
+{ better TMT Pascal support and under instruction }
+{ from Prof. Abimbola Olowofoyeku (The African Chief),}
+{ I have added better Gnu Pascal support }
+{ }
+{ April 30 2003 - DL : under instruction from David Mears AKA }
+{ Jason Siletto, I have added FPC Linux support. }
+{ This was compiled with fpc 1.1, so remember to set }
+{ include file path. ie. -Fi/usr/share/fpcsrc/rtl/* }
+{ }
+{
+ $Log: sdl_mixer.pas,v $
+ Revision 1.18 2007/05/29 21:31:44 savage
+ Changes as suggested by Almindor for 64bit compatibility.
+
+ Revision 1.17 2007/05/20 20:31:17 savage
+ Initial Changes to Handle 64 Bits
+
+ Revision 1.16 2006/12/02 00:16:17 savage
+ Updated to latest version
+
+ Revision 1.15 2005/04/10 11:48:33 savage
+ Changes as suggested by Michalis, thanks.
+
+ Revision 1.14 2005/02/24 20:20:07 savage
+ Changed definition of MusicType and added GetMusicType function
+
+ Revision 1.13 2005/01/05 01:47:09 savage
+ Changed LibName to reflect what MacOS X should have. ie libSDL*-1.2.0.dylib respectively.
+
+ Revision 1.12 2005/01/04 23:14:56 savage
+ Changed LibName to reflect what most Linux distros will have. ie libSDL*-1.2.so.0 respectively.
+
+ Revision 1.11 2005/01/01 02:05:19 savage
+ Updated to v1.2.6
+
+ Revision 1.10 2004/09/12 21:45:17 savage
+ Robert Reed spotted that Mix_SetMusicPosition was missing from the conversion, so this has now been added.
+
+ Revision 1.9 2004/08/27 21:48:24 savage
+ IFDEFed out Smpeg support on MacOS X
+
+ Revision 1.8 2004/08/14 22:54:30 savage
+ Updated so that Library name defines are correctly defined for MacOS X.
+
+ Revision 1.7 2004/05/10 14:10:04 savage
+ Initial MacOS X support. Fixed defines for MACOS ( Classic ) and DARWIN ( MacOS X ).
+
+ Revision 1.6 2004/04/13 09:32:08 savage
+ Changed Shared object names back to just the .so extension to avoid conflicts on various Linux/Unix distros. Therefore developers will need to create Symbolic links to the actual Share Objects if necessary.
+
+ Revision 1.5 2004/04/01 20:53:23 savage
+ Changed Linux Shared Object names so they reflect the Symbolic Links that are created when installing the RPMs from the SDL site.
+
+ Revision 1.4 2004/03/31 22:20:02 savage
+ Windows unit not used in this file, so it was removed to keep the code tidy.
+
+ Revision 1.3 2004/03/31 10:05:08 savage
+ Better defines for Endianess under FreePascal and Borland compilers.
+
+ Revision 1.2 2004/03/30 20:23:28 savage
+ Tidied up use of UNIX compiler directive.
+
+ Revision 1.1 2004/02/14 23:35:42 savage
+ version 1 of sdl_image, sdl_mixer and smpeg.
+
+
+}
+{******************************************************************************}
+
+{$I jedi-sdl.inc}
+
+interface
+
+uses
+{$IFDEF __GPC__}
+ gpc,
+{$ENDIF}
+{$IFNDEF DARWIN}
+{$IFNDEF no_smpeg}
+ smpeg,
+{$ENDIF}
+{$ENDIF}
+ sdl;
+
+const
+{$IFDEF WINDOWS}
+ SDL_MixerLibName = 'SDL_mixer.dll';
+{$ENDIF}
+
+{$IFDEF UNIX}
+{$IFDEF DARWIN}
+ SDL_MixerLibName = 'libSDL_mixer-1.2.0.dylib';
+{$ELSE}
+ {$IFDEF FPC}
+ SDL_MixerLibName = 'libSDL_mixer.so';
+ {$ELSE}
+ SDL_MixerLibName = 'libSDL_mixer-1.2.so.0';
+ {$ENDIF}
+{$ENDIF}
+{$ENDIF}
+
+{$IFDEF MACOS}
+ SDL_MixerLibName = 'SDL_mixer';
+{$ENDIF}
+
+ {* Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL *}
+ SDL_MIXER_MAJOR_VERSION = 1;
+{$EXTERNALSYM MIX_MAJOR_VERSION}
+ SDL_MIXER_MINOR_VERSION = 2;
+{$EXTERNALSYM MIX_MINOR_VERSION}
+ SDL_MIXER_PATCHLEVEL = 7;
+{$EXTERNALSYM MIX_PATCHLEVEL}
+
+ // Backwards compatibility
+ MIX_MAJOR_VERSION = SDL_MIXER_MAJOR_VERSION;
+ MIX_MINOR_VERSION = SDL_MIXER_MINOR_VERSION;
+ MIX_PATCHLEVEL = SDL_MIXER_PATCHLEVEL;
+
+ // SDL_Mixer.h constants
+ { The default mixer has 8 simultaneous mixing channels }
+{$IFNDEF MIX_CHANNELS}
+ MIX_CHANNELS = 8;
+{$ENDIF}
+{$EXTERNALSYM MIX_CHANNELS}
+ { Good default values for a PC soundcard }
+ MIX_DEFAULT_FREQUENCY = 22050;
+{$EXTERNALSYM MIX_DEFAULT_FREQUENCY}
+
+{$IFDEF IA32}
+ MIX_DEFAULT_FORMAT = AUDIO_S16LSB;
+{$ELSE}
+ MIX_DEFAULT_FORMAT = AUDIO_S16MSB;
+{$ENDIF}
+{$EXTERNALSYM MIX_DEFAULT_FORMAT}
+
+ MIX_DEFAULT_CHANNELS = 2;
+{$EXTERNALSYM MIX_DEFAULT_CHANNELS}
+ MIX_MAX_VOLUME = 128; { Volume of a chunk }
+{$EXTERNALSYM MIX_MAX_VOLUME}
+
+ PATH_MAX = 255;
+
+ // mikmod.h constants
+ {*
+ * Library version
+ *}
+ LIBMIKMOD_VERSION_MAJOR = 3;
+ LIBMIKMOD_VERSION_MINOR = 1;
+ LIBMIKMOD_REVISION = 8;
+ LIBMIKMOD_VERSION = ( ( LIBMIKMOD_VERSION_MAJOR shl 16 ) or
+ ( LIBMIKMOD_VERSION_MINOR shl 8 ) or
+ ( LIBMIKMOD_REVISION ) );
+
+type
+ //music_cmd.h types
+ PMusicCMD = ^TMusicCMD;
+ TMusicCMD = record
+ filename : array[ 0..PATH_MAX - 1 ] of char;
+ cmd : array[ 0..PATH_MAX - 1 ] of char;
+ pid : TSYS_ThreadHandle;
+ end;
+
+ //wavestream.h types
+ PWAVStream = ^TWAVStream;
+ TWAVStream = record
+ wavefp : Pointer;
+ start : longint;
+ stop : longint;
+ cvt : TSDL_AudioCVT;
+ end;
+
+ //playmidi.h types
+ PMidiEvent = ^TMidiEvent;
+ TMidiEvent = record
+ time : Longint;
+ channel : uint8;
+ type_ : uint8;
+ a : uint8;
+ b : uint8;
+ end;
+
+ PMidiSong = ^TMidiSong;
+ TMidiSong = record
+ samples : Longint;
+ events : PMidiEvent;
+ end;
+
+ //music_ogg.h types
+ POGG_Music = ^TOGG_Music;
+ TOGG_Music = record
+ playing : integer;
+ volume : integer;
+ //vf: OggVorbis_File;
+ section : integer;
+ cvt : TSDL_AudioCVT;
+ len_available : integer;
+ snd_available : PUint8;
+ end;
+
+ // mikmod.h types
+ {*
+ * Error codes
+ *}
+ TErrorEnum = (
+ MMERR_OPENING_FILE,
+ MMERR_OUT_OF_MEMORY,
+ MMERR_DYNAMIC_LINKING,
+ MMERR_SAMPLE_TOO_BIG,
+ MMERR_OUT_OF_HANDLES,
+ MMERR_UNKNOWN_WAVE_TYPE,
+ MMERR_LOADING_PATTERN,
+ MMERR_LOADING_TRACK,
+ MMERR_LOADING_HEADER,
+ MMERR_LOADING_SAMPLEINFO,
+ MMERR_NOT_A_MODULE,
+ MMERR_NOT_A_STREAM,
+ MMERR_MED_SYNTHSAMPLES,
+ MMERR_ITPACK_INVALID_DATA,
+ MMERR_DETECTING_DEVICE,
+ MMERR_INVALID_DEVICE,
+ MMERR_INITIALIZING_MIXER,
+ MMERR_OPENING_AUDIO,
+ MMERR_8BIT_ONLY,
+ MMERR_16BIT_ONLY,
+ MMERR_STEREO_ONLY,
+ MMERR_ULAW,
+ MMERR_NON_BLOCK,
+ MMERR_AF_AUDIO_PORT,
+ MMERR_AIX_CONFIG_INIT,
+ MMERR_AIX_CONFIG_CONTROL,
+ MMERR_AIX_CONFIG_START,
+ MMERR_GUS_SETTINGS,
+ MMERR_GUS_RESET,
+ MMERR_GUS_TIMER,
+ MMERR_HP_SETSAMPLESIZE,
+ MMERR_HP_SETSPEED,
+ MMERR_HP_CHANNELS,
+ MMERR_HP_AUDIO_OUTPUT,
+ MMERR_HP_AUDIO_DESC,
+ MMERR_HP_BUFFERSIZE,
+ MMERR_OSS_SETFRAGMENT,
+ MMERR_OSS_SETSAMPLESIZE,
+ MMERR_OSS_SETSTEREO,
+ MMERR_OSS_SETSPEED,
+ MMERR_SGI_SPEED,
+ MMERR_SGI_16BIT,
+ MMERR_SGI_8BIT,
+ MMERR_SGI_STEREO,
+ MMERR_SGI_MONO,
+ MMERR_SUN_INIT,
+ MMERR_OS2_MIXSETUP,
+ MMERR_OS2_SEMAPHORE,
+ MMERR_OS2_TIMER,
+ MMERR_OS2_THREAD,
+ MMERR_DS_PRIORITY,
+ MMERR_DS_BUFFER,
+ MMERR_DS_FORMAT,
+ MMERR_DS_NOTIFY,
+ MMERR_DS_EVENT,
+ MMERR_DS_THREAD,
+ MMERR_DS_UPDATE,
+ MMERR_WINMM_HANDLE,
+ MMERR_WINMM_ALLOCATED,
+ MMERR_WINMM_DEVICEID,
+ MMERR_WINMM_FORMAT,
+ MMERR_WINMM_UNKNOWN,
+ MMERR_MAC_SPEED,
+ MMERR_MAC_START,
+ MMERR_MAX
+ );
+
+ PMODULE = ^TMODULE;
+ TMODULE = record
+ (* general module information *)
+ //CHAR* songname; (* name of the song *)
+ //CHAR* modtype; (* string type of module loaded *)
+ //CHAR* comment; (* module comments *)
+ //UWORD flags; (* See module flags above *)
+ //UBYTE numchn; (* number of module channels *)
+ //UBYTE numvoices; (* max # voices used for full NNA playback *)
+ //UWORD numpos; (* number of positions in this song *)
+ //UWORD numpat; (* number of patterns in this song *)
+ //UWORD numins; (* number of instruments *)
+ //UWORD numsmp; (* number of samples *)
+ //type = record INSTRUMENT* instruments; (* all instruments *)
+ //type = record SAMPLE* samples; (* all samples *)
+ //UBYTE realchn; (* real number of channels used *)
+ //UBYTE totalchn; (* total number of channels used (incl NNAs) *)
+ (* playback settings *)
+ //UWORD reppos; (* restart position *)
+ //UBYTE initspeed; (* initial song speed *)
+ //UWORD inittempo; (* initial song tempo *)
+ //UBYTE initvolume; (* initial global volume (0 - 128) *)
+ //UWORD panning : array[ 0..64- 1 ] of ; (* 64 panning positions *)
+ //UBYTE chanvol : array[ 0..64- 1 ] of ; (* 64 channel positions *)
+ //UWORD bpm; (* current beats-per-minute speed *)
+ //UWORD sngspd; (* current song speed *)
+ //SWORD volume; (* song volume (0-128) (or user volume) *)
+ //BOOL extspd; (* extended speed flag (default enabled) *)
+ //BOOL panflag; (* panning flag (default enabled) *)
+ //BOOL wrap; (* wrap module ? (default disabled) *)
+ //BOOL loop; (* allow module to loop ? (default enabled) *)
+ //BOOL fadeout; (* volume fade out during last pattern *)
+ //UWORD patpos; (* current row number *)
+ //SWORD sngpos; (* current song position *)
+ //ULONG sngtime; (* current song time in 2^-10 seconds *)
+ //SWORD relspd; (* relative speed factor *)
+ (* internal module representation *)
+ //UWORD numtrk; (* number of tracks *)
+ //UBYTE** tracks; (* array of numtrk pointers to tracks *)
+ //UWORD* patterns; (* array of Patterns *)
+ //UWORD* pattrows; (* array of number of rows for each pattern *)
+ //UWORD* positions; (* all positions *)
+ //BOOL forbid; (* if true, no player updatenot *)
+ //UWORD numrow; (* number of rows on current pattern *)
+ //UWORD vbtick; (* tick counter (counts from 0 to sngspd) *)
+ //UWORD sngremainder;(* used for song time computation *)
+ //type = record MP_CONTROL* control; (* Effects Channel info (size pf.numchn) *)
+ //type = record MP_VOICE* voice; (* Audio Voice information (size md_numchn) *)
+ //UBYTE globalslide; (* global volume slide rate *)
+ //UBYTE pat_repcrazy;(* module has just looped to position -1 *)
+ //UWORD patbrk; (* position where to start a new pattern *)
+ //UBYTE patdly; (* patterndelay counter (command memory) *)
+ //UBYTE patdly2; (* patterndelay counter (real one) *)
+ //SWORD posjmp; (* flag to indicate a jump is needed... *)
+ end;
+
+ PUNIMOD = ^TUNIMOD;
+ TUNIMOD = TMODULE;
+
+ //SDL_mixer.h types
+ { The internal format for an audio chunk }
+ PMix_Chunk = ^TMix_Chunk;
+ TMix_Chunk = record
+ allocated : integer;
+ abuf : PUint8;
+ alen : Uint32;
+ volume : Uint8; { Per-sample volume, 0-128 }
+ end;
+ Mix_Chunk = TMix_Chunk;
+
+ { The different fading types supported }
+ TMix_Fading = (
+ MIX_NO_FADING,
+ MIX_FADING_OUT,
+ MIX_FADING_IN
+ );
+ Mix_Fading = TMix_Fading;
+
+ TMix_MusicType = (
+ MUS_NONE,
+ MUS_CMD,
+ MUS_WAV,
+ MUS_MOD,
+ MUS_MID,
+ MUS_OGG,
+ MUS_MP3
+ );
+ Mix_MusicType = TMix_MusicType;
+
+ TMusicUnion = record
+ case Byte of
+ 0 : ( cmd : PMusicCMD );
+ 1 : ( wave : PWAVStream );
+ 2 : ( module : PUNIMOD );
+ 3 : ( midi : TMidiSong );
+ 4 : ( ogg : POGG_music );
+ {$IFNDEF DARWIN}
+ 5 : ( mp3 : PSMPEG );
+ {$ENDIF}
+ end;
+
+ P_Mix_Music = ^T_Mix_Music;
+ T_Mix_Music = record
+ type_ : TMix_MusicType;
+ data : TMusicUnion;
+ fading : TMix_Fading;
+ fade_volume : integer;
+ fade_step : integer;
+ fade_steps : integer;
+ error : integer;
+ end;
+
+ { The internal format for a music chunk interpreted via mikmod }
+ PMix_Music = ^TMix_Music;
+ TMix_Music = T_Mix_Music;
+
+ {$IFNDEF __GPC__}
+ TMixFunction = function( udata : Pointer; stream : PUint8; len : integer ) : Pointer; cdecl;
+ {$ELSE}
+ TMixFunction = function( udata : Pointer; stream : PUint8; len : integer ) : Pointer;
+ {$ENDIF}
+
+{ This macro can be used to fill a version structure with the compile-time
+ version of the SDL_mixer library. }
+procedure SDL_MIXER_VERSION(var X: TSDL_Version);
+{$EXTERNALSYM SDL_MIXER_VERSION}
+
+{ This function gets the version of the dynamically linked SDL_mixer library.
+ It should NOT be used to fill a version structure, instead you should use the
+ SDL_MIXER_VERSION() macro. }
+function Mix_Linked_Version : PSDL_version;
+cdecl; external {$IFDEF __GPC__}name 'Mix_Linked_Version'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_Linked_Version}
+
+{ Open the mixer with a certain audio format }
+function Mix_OpenAudio( frequency : integer; format : Uint16; channels :
+ integer; chunksize : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_OpenAudio'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_OpenAudio}
+
+{ Dynamically change the number of channels managed by the mixer.
+ If decreasing the number of channels, the upper channels are
+ stopped.
+ This function returns the new number of allocated channels.
+ }
+function Mix_AllocateChannels( numchannels : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_AllocateChannels'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_AllocateChannels}
+
+{ Find out what the actual audio device parameters are.
+ This function returns 1 if the audio has been opened, 0 otherwise.
+ }
+function Mix_QuerySpec( var frequency : integer; var format : Uint16; var channels : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_QuerySpec'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_QuerySpec}
+
+{ Load a wave file or a music (.mod .s3m .it .xm) file }
+function Mix_LoadWAV_RW( src : PSDL_RWops; freesrc : integer ) : PMix_Chunk;
+cdecl; external {$IFDEF __GPC__}name 'Mix_LoadWAV_RW'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_LoadWAV_RW}
+
+function Mix_LoadWAV( filename : PChar ) : PMix_Chunk;
+
+function Mix_LoadMUS( const filename : PChar ) : PMix_Music;
+cdecl; external {$IFDEF __GPC__}name 'Mix_LoadMUS'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_LoadMUS}
+
+(*#if 0 { This hasn't been hooked into music.c yet }
+{ Load a music file from an SDL_RWop object (MikMod-specific currently)
+ Matt Campbell (matt@campbellhome.dhs.org) April 2000 }
+function Mix_LoadMUS_RW(SDL_RWops *rw) : PMix_Music; cdecl;
+#endif*)
+
+{ Load a wave file of the mixer format from a memory buffer }
+function Mix_QuickLoad_WAV( mem : PUint8 ) : PMix_Chunk;
+cdecl; external {$IFDEF __GPC__}name 'Mix_QuickLoad_WAV'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_QuickLoad_WAV}
+
+{ Free an audio chunk previously loaded }
+procedure Mix_FreeChunk( chunk : PMix_Chunk );
+cdecl; external {$IFDEF __GPC__}name 'Mix_FreeChunk'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_FreeChunk}
+
+procedure Mix_FreeMusic( music : PMix_Music );
+cdecl; external {$IFDEF __GPC__}name 'Mix_FreeMusic'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_FreeMusic}
+
+{ Find out the music format of a mixer music, or the currently playing
+ music, if 'music' is NULL.}
+function Mix_GetMusicType( music : PMix_Music ) : TMix_MusicType;
+cdecl; external {$IFDEF __GPC__}name 'Mix_GetMusicType'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_GetMusicType}
+
+{ Set a function that is called after all mixing is performed.
+ This can be used to provide real-time visual display of the audio stream
+ or add a custom mixer filter for the stream data.
+}
+procedure Mix_SetPostMix( mix_func : TMixFunction; arg : Pointer );
+cdecl; external {$IFDEF __GPC__}name 'Mix_SetPostMix'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_SetPostMix}
+
+{ Add your own music player or additional mixer function.
+ If 'mix_func' is NULL, the default music player is re-enabled.
+ }
+procedure Mix_HookMusic( mix_func : TMixFunction; arg : Pointer );
+ cdecl; external {$IFDEF __GPC__}name 'Mix_HookMusic'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_HookMusic}
+
+{ Add your own callback when the music has finished playing.
+ }
+procedure Mix_HookMusicFinished( music_finished : Pointer );
+cdecl; external {$IFDEF __GPC__}name 'Mix_HookMusicFinished'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_HookMusicFinished}
+
+{ Get a pointer to the user data for the current music hook }
+function Mix_GetMusicHookData : Pointer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_GetMusicHookData'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_GetMusicHookData}
+
+{* Add your own callback when a channel has finished playing. NULL
+ * to disable callback.*}
+type
+ {$IFNDEF __GPC__}
+ TChannel_finished = procedure( channel: Integer ); cdecl;
+ {$ELSE}
+ TChannel_finished = procedure( channel: Integer );
+ {$ENDIF}
+
+procedure Mix_ChannelFinished( channel_finished : TChannel_finished );
+cdecl; external {$IFDEF __GPC__}name 'Mix_ChannelFinished'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_ChannelFinished}
+
+const
+ MIX_CHANNEL_POST = -2;
+
+ {* This is the format of a special effect callback:
+ *
+ * myeffect(int chan, void *stream, int len, void *udata);
+ *
+ * (chan) is the channel number that your effect is affecting. (stream) is
+ * the buffer of data to work upon. (len) is the size of (stream), and
+ * (udata) is a user-defined bit of data, which you pass as the last arg of
+ * Mix_RegisterEffect(), and is passed back unmolested to your callback.
+ * Your effect changes the contents of (stream) based on whatever parameters
+ * are significant, or just leaves it be, if you prefer. You can do whatever
+ * you like to the buffer, though, and it will continue in its changed state
+ * down the mixing pipeline, through any other effect functions, then finally
+ * to be mixed with the rest of the channels and music for the final output
+ * stream.
+ *}
+type
+ {$IFNDEF __GPC__}
+ TMix_EffectFunc = function( chan : integer; stream : Pointer; len : integer; udata : Pointer ) : Pointer; cdecl;
+ {$ELSE}
+ TMix_EffectFunc = function( chan : integer; stream : Pointer; len : integer; udata : Pointer ) : Pointer;
+ {$ENDIF}
+ {*
+ * This is a callback that signifies that a channel has finished all its
+ * loops and has completed playback. This gets called if the buffer
+ * plays out normally, or if you call Mix_HaltChannel(), implicitly stop
+ * a channel via Mix_AllocateChannels(), or unregister a callback while
+ * it's still playing.
+ *}
+ {$IFNDEF __GPC__}
+ TMix_EffectDone = function( chan : integer; udata : Pointer ) : Pointer; cdecl;
+ {$ELSE}
+ TMix_EffectDone = function( chan : integer; udata : Pointer ) : Pointer;
+ {$ENDIF}
+ {* Register a special effect function. At mixing time, the channel data is
+ * copied into a buffer and passed through each registered effect function.
+ * After it passes through all the functions, it is mixed into the final
+ * output stream. The copy to buffer is performed once, then each effect
+ * function performs on the output of the previous effect. Understand that
+ * this extra copy to a buffer is not performed if there are no effects
+ * registered for a given chunk, which saves CPU cycles, and any given
+ * effect will be extra cycles, too, so it is crucial that your code run
+ * fast. Also note that the data that your function is given is in the
+ * format of the sound device, and not the format you gave to Mix_OpenAudio(),
+ * although they may in reality be the same. This is an unfortunate but
+ * necessary speed concern. Use Mix_QuerySpec() to determine if you can
+ * handle the data before you register your effect, and take appropriate
+ * actions.
+ * You may also specify a callback (Mix_EffectDone_t) that is called when
+ * the channel finishes playing. This gives you a more fine-grained control
+ * than Mix_ChannelFinished(), in case you need to free effect-specific
+ * resources, etc. If you don't need this, you can specify NULL.
+ * You may set the callbacks before or after calling Mix_PlayChannel().
+ * Things like Mix_SetPanning() are just internal special effect functions,
+ * so if you are using that, you've already incurred the overhead of a copy
+ * to a separate buffer, and that these effects will be in the queue with
+ * any functions you've registered. The list of registered effects for a
+ * channel is reset when a chunk finishes playing, so you need to explicitly
+ * set them with each call to Mix_PlayChannel*().
+ * You may also register a special effect function that is to be run after
+ * final mixing occurs. The rules for these callbacks are identical to those
+ * in Mix_RegisterEffect, but they are run after all the channels and the
+ * music have been mixed into a single stream, whereas channel-specific
+ * effects run on a given channel before any other mixing occurs. These
+ * global effect callbacks are call "posteffects". Posteffects only have
+ * their Mix_EffectDone_t function called when they are unregistered (since
+ * the main output stream is never "done" in the same sense as a channel).
+ * You must unregister them manually when you've had enough. Your callback
+ * will be told that the channel being mixed is (MIX_CHANNEL_POST) if the
+ * processing is considered a posteffect.
+ *
+ * After all these effects have finished processing, the callback registered
+ * through Mix_SetPostMix() runs, and then the stream goes to the audio
+ * device.
+ *
+ * returns zero if error (no such channel), nonzero if added.
+ * Error messages can be retrieved from Mix_GetError().
+ *}
+function Mix_RegisterEffect( chan : integer; f : TMix_EffectFunc; d : TMix_EffectDone; arg : Pointer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_RegisterEffect'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_RegisterEffect}
+
+{* You may not need to call this explicitly, unless you need to stop an
+ * effect from processing in the middle of a chunk's playback.
+ * Posteffects are never implicitly unregistered as they are for channels,
+ * but they may be explicitly unregistered through this function by
+ * specifying MIX_CHANNEL_POST for a channel.
+ * returns zero if error (no such channel or effect), nonzero if removed.
+ * Error messages can be retrieved from Mix_GetError().
+ *}
+function Mix_UnregisterEffect( channel : integer; f : TMix_EffectFunc ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_UnregisterEffect'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_UnregisterEffect}
+
+ {* You may not need to call this explicitly, unless you need to stop all
+ * effects from processing in the middle of a chunk's playback. Note that
+ * this will also shut off some internal effect processing, since
+ * Mix_SetPanning( ) and others may use this API under the hood.This is
+ * called internally when a channel completes playback.
+ * Posteffects are never implicitly unregistered as they are for channels,
+ * but they may be explicitly unregistered through this function by
+ * specifying MIX_CHANNEL_POST for a channel.
+ * returns zero if error( no such channel ), nonzero if all effects removed.
+ * Error messages can be retrieved from Mix_GetError( ).
+ *}
+function Mix_UnregisterAllEffects( channel : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_UnregisterAllEffects'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_UnregisterAllEffects}
+
+const
+ MIX_EFFECTSMAXSPEED = 'MIX_EFFECTSMAXSPEED';
+
+ {*
+ * These are the internally - defined mixing effects.They use the same API that
+ * effects defined in the application use, but are provided here as a
+ * convenience.Some effects can reduce their quality or use more memory in
+ * the name of speed; to enable this, make sure the environment variable
+ * MIX_EFFECTSMAXSPEED( see above ) is defined before you call
+ * Mix_OpenAudio( ).
+ * }
+
+ {* set the panning of a channel.The left and right channels are specified
+ * as integers between 0 and 255, quietest to loudest, respectively.
+ *
+ * Technically, this is just individual volume control for a sample with
+ * two( stereo )channels, so it can be used for more than just panning.
+ * if you want real panning, call it like this :
+ *
+ * Mix_SetPanning( channel, left, 255 - left );
+ *
+ * ...which isn't so hard.
+ *
+ * Setting( channel ) to MIX_CHANNEL_POST registers this as a posteffect, and
+ * the panning will be done to the final mixed stream before passing it on
+ * to the audio device.
+ *
+ * This uses the Mix_RegisterEffect( )API internally, and returns without
+ * registering the effect function if the audio device is not configured
+ * for stereo output.Setting both( left ) and ( right ) to 255 causes this
+ * effect to be unregistered, since that is the data's normal state.
+ *
+ * returns zero if error( no such channel or Mix_RegisterEffect( )fails ),
+ * nonzero if panning effect enabled.Note that an audio device in mono
+ * mode is a no - op, but this call will return successful in that case .
+ * Error messages can be retrieved from Mix_GetError( ).
+ * }
+ function Mix_SetPanning( channel : integer; left : Uint8; right : Uint8 ) : integer;
+ cdecl; external {$IFDEF __GPC__}name 'Mix_SetPanning'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+ {$EXTERNALSYM Mix_SetPanning}
+
+ { * set the position ofa channel.( angle ) is an integer from 0 to 360, that
+ * specifies the location of the sound in relation to the listener.( angle )
+ * will be reduced as neccesary( 540 becomes 180 degrees, -100 becomes 260 ).
+ * Angle 0 is due north, and rotates clockwise as the value increases.
+ * for efficiency, the precision of this effect may be limited( angles 1
+ * through 7 might all produce the same effect, 8 through 15 are equal, etc ).
+ * ( distance ) is an integer between 0 and 255 that specifies the space
+ * between the sound and the listener.The larger the number, the further
+ * away the sound is .Using 255 does not guarantee that the channel will be
+ * culled from the mixing process or be completely silent.For efficiency,
+ * the precision of this effect may be limited( distance 0 through 5 might
+ * all produce the same effect, 6 through 10 are equal, etc ).Setting( angle )
+ * and ( distance ) to 0 unregisters this effect, since the data would be
+ * unchanged.
+ *
+ * if you need more precise positional audio, consider using OpenAL for
+ * spatialized effects instead of SDL_mixer.This is only meant to be a
+ * basic effect for simple "3D" games.
+ *
+ * if the audio device is configured for mono output, then you won't get
+ * any effectiveness from the angle; however, distance attenuation on the
+ * channel will still occur.While this effect will function with stereo
+ * voices, it makes more sense to use voices with only one channel of sound,
+ * so when they are mixed through this effect, the positioning will sound
+ * correct.You can convert them to mono through SDL before giving them to
+ * the mixer in the first place if you like.
+ *
+ * Setting( channel ) to MIX_CHANNEL_POST registers this as a posteffect, and
+ * the positioning will be done to the final mixed stream before passing it
+ * on to the audio device.
+ *
+ * This is a convenience wrapper over Mix_SetDistance( ) and Mix_SetPanning( ).
+ *
+ * returns zero if error( no such channel or Mix_RegisterEffect( )fails ),
+ * nonzero if position effect is enabled.
+ * Error messages can be retrieved from Mix_GetError( ).
+ * }
+ function Mix_SetPosition( channel :integer; angle : Sint16; distance : Uint8 ) : integer;
+ cdecl; external {$IFDEF __GPC__}name 'Mix_SetPosition'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+ {$EXTERNALSYM Mix_SetPosition}
+
+ {* set the "distance" of a channel.( distance ) is an integer from 0 to 255
+ * that specifies the location of the sound in relation to the listener.
+ * Distance 0 is overlapping the listener, and 255 is as far away as possible
+ * A distance of 255 does not guarantee silence; in such a case , you might
+ * want to try changing the chunk's volume, or just cull the sample from the
+ * mixing process with Mix_HaltChannel( ).
+ * for efficiency, the precision of this effect may be limited( distances 1
+ * through 7 might all produce the same effect, 8 through 15 are equal, etc ).
+ * ( distance ) is an integer between 0 and 255 that specifies the space
+ * between the sound and the listener.The larger the number, the further
+ * away the sound is .
+ * Setting( distance ) to 0 unregisters this effect, since the data would be
+ * unchanged.
+ * if you need more precise positional audio, consider using OpenAL for
+ * spatialized effects instead of SDL_mixer.This is only meant to be a
+ * basic effect for simple "3D" games.
+ *
+ * Setting( channel ) to MIX_CHANNEL_POST registers this as a posteffect, and
+ * the distance attenuation will be done to the final mixed stream before
+ * passing it on to the audio device.
+ *
+ * This uses the Mix_RegisterEffect( )API internally.
+ *
+ * returns zero if error( no such channel or Mix_RegisterEffect( )fails ),
+ * nonzero if position effect is enabled.
+ * Error messages can be retrieved from Mix_GetError( ).
+ * }
+ function Mix_SetDistance( channel : integer; distance : Uint8 ) : integer;
+ cdecl; external {$IFDEF __GPC__}name 'Mix_SetDistance'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+ {$EXTERNALSYM Mix_SetDistance}
+ { *
+ * !!! FIXME : Haven't implemented, since the effect goes past the
+ * end of the sound buffer.Will have to think about this.
+ * - -ryan.
+ * /
+ { if 0
+ { * Causes an echo effect to be mixed into a sound.( echo ) is the amount
+ * of echo to mix.0 is no echo, 255 is infinite( and probably not
+ * what you want ).
+ *
+ * Setting( channel ) to MIX_CHANNEL_POST registers this as a posteffect, and
+ * the reverbing will be done to the final mixed stream before passing it on
+ * to the audio device.
+ *
+ * This uses the Mix_RegisterEffect( )API internally.If you specify an echo
+ * of zero, the effect is unregistered, as the data is already in that state.
+ *
+ * returns zero if error( no such channel or Mix_RegisterEffect( )fails ),
+ * nonzero if reversing effect is enabled.
+ * Error messages can be retrieved from Mix_GetError( ).
+ *
+ extern no_parse_DECLSPEC int Mix_SetReverb( int channel, Uint8 echo );
+ #E ndif}
+ { * Causes a channel to reverse its stereo.This is handy if the user has his
+ * speakers hooked up backwards, or you would like to have a minor bit of
+ * psychedelia in your sound code. : )Calling this function with ( flip )
+ * set to non - zero reverses the chunks's usual channels. If (flip) is zero,
+ * the effect is unregistered.
+ *
+ * This uses the Mix_RegisterEffect( )API internally, and thus is probably
+ * more CPU intensive than having the user just plug in his speakers
+ * correctly.Mix_SetReverseStereo( )returns without registering the effect
+ * function if the audio device is not configured for stereo output.
+ *
+ * if you specify MIX_CHANNEL_POST for ( channel ), then this the effect is used
+ * on the final mixed stream before sending it on to the audio device( a
+ * posteffect ).
+ *
+ * returns zero if error( no such channel or Mix_RegisterEffect( )fails ),
+ * nonzero if reversing effect is enabled.Note that an audio device in mono
+ * mode is a no - op, but this call will return successful in that case .
+ * Error messages can be retrieved from Mix_GetError( ).
+ * }
+ function Mix_SetReverseStereo( channel : integer; flip : integer ) : integer;
+ cdecl; external {$IFDEF __GPC__}name 'Mix_SetReverseStereo'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+ {$EXTERNALSYM Mix_SetReverseStereo}
+ { end of effects API. - -ryan. *}
+
+{ Reserve the first channels (0 -> n-1) for the application, i.e. don't allocate
+ them dynamically to the next sample if requested with a -1 value below.
+ Returns the number of reserved channels.
+ }
+function Mix_ReserveChannels( num : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_ReserveChannels'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_ReserveChannels}
+
+{ Channel grouping functions }
+
+{ Attach a tag to a channel. A tag can be assigned to several mixer
+ channels, to form groups of channels.
+ If 'tag' is -1, the tag is removed (actually -1 is the tag used to
+ represent the group of all the channels).
+ Returns true if everything was OK.
+ }
+function Mix_GroupChannel( which : integer; tag : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_GroupChannel'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_GroupChannel}
+
+{ Assign several consecutive channels to a group }
+function Mix_GroupChannels( from : integer; to_ : integer; tag : integer ) :
+integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_GroupChannels'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_GroupChannels}
+
+{ Finds the first available channel in a group of channels }
+function Mix_GroupAvailable( tag : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_GroupAvailable'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_GroupAvailable}
+
+{ Returns the number of channels in a group. This is also a subtle
+ way to get the total number of channels when 'tag' is -1
+ }
+function Mix_GroupCount( tag : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_GroupCount'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_GroupCount}
+
+{ Finds the "oldest" sample playing in a group of channels }
+function Mix_GroupOldest( tag : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_GroupOldest'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_GroupOldest}
+
+{ Finds the "most recent" (i.e. last) sample playing in a group of channels }
+function Mix_GroupNewer( tag : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_GroupNewer'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_GroupNewer}
+
+{ The same as above, but the sound is played at most 'ticks' milliseconds }
+function Mix_PlayChannelTimed( channel : integer; chunk : PMix_Chunk; loops : integer; ticks : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_PlayChannelTimed'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_PlayChannelTimed}
+
+{ Play an audio chunk on a specific channel.
+ If the specified channel is -1, play on the first free channel.
+ If 'loops' is greater than zero, loop the sound that many times.
+ If 'loops' is -1, loop inifinitely (~65000 times).
+ Returns which channel was used to play the sound.
+}
+function Mix_PlayChannel( channel : integer; chunk : PMix_Chunk; loops : integer ) : integer;
+
+function Mix_PlayMusic( music : PMix_Music; loops : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_PlayMusic'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_PlayMusic}
+
+{ Fade in music or a channel over "ms" milliseconds, same semantics as the "Play" functions }
+function Mix_FadeInMusic( music : PMix_Music; loops : integer; ms : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_FadeInMusic'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_FadeInMusic}
+
+function Mix_FadeInChannelTimed( channel : integer; chunk : PMix_Chunk; loops : integer; ms : integer; ticks : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_FadeInChannelTimed'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_FadeInChannelTimed}
+
+function Mix_FadeInChannel( channel : integer; chunk : PMix_Chunk; loops : integer; ms : integer ) : integer;
+
+{ Set the volume in the range of 0-128 of a specific channel or chunk.
+ If the specified channel is -1, set volume for all channels.
+ Returns the original volume.
+ If the specified volume is -1, just return the current volume.
+}
+function Mix_Volume( channel : integer; volume : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_Volume'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_Volume}
+
+function Mix_VolumeChunk( chunk : PMix_Chunk; volume : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_VolumeChunk'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_VolumeChunk}
+
+function Mix_VolumeMusic( volume : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_VolumeMusic'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_VolumeMusic}
+
+{ Halt playing of a particular channel }
+function Mix_HaltChannel( channel : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_HaltChannel'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_HaltChannel}
+
+function Mix_HaltGroup( tag : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_HaltGroup'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_HaltGroup}
+
+function Mix_HaltMusic : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_HaltMusic'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_HaltMusic}
+
+{ Change the expiration delay for a particular channel.
+ The sample will stop playing after the 'ticks' milliseconds have elapsed,
+ or remove the expiration if 'ticks' is -1
+}
+function Mix_ExpireChannel( channel : integer; ticks : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_ExpireChannel'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_ExpireChannel}
+
+{ Halt a channel, fading it out progressively till it's silent
+ The ms parameter indicates the number of milliseconds the fading
+ will take.
+ }
+function Mix_FadeOutChannel( which : integer; ms : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_FadeOutChannel'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_FadeOutChannel}
+function Mix_FadeOutGroup( tag : integer; ms : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_FadeOutGroup'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_FadeOutGroup}
+function Mix_FadeOutMusic( ms : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_FadeOutMusic'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_FadeOutMusic}
+
+{ Query the fading status of a channel }
+function Mix_FadingMusic : TMix_Fading;
+cdecl; external {$IFDEF __GPC__}name 'Mix_FadingMusic'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_FadingMusic}
+
+function Mix_FadingChannel( which : integer ) : TMix_Fading;
+cdecl; external {$IFDEF __GPC__}name 'Mix_FadingChannel'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_FadingChannel}
+
+{ Pause/Resume a particular channel }
+procedure Mix_Pause( channel : integer );
+cdecl; external {$IFDEF __GPC__}name 'Mix_Pause'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_Pause}
+
+procedure Mix_Resume( channel : integer );
+cdecl; external {$IFDEF __GPC__}name 'Mix_Resume'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_Resume}
+
+function Mix_Paused( channel : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_Paused'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_Paused}
+
+{ Pause/Resume the music stream }
+procedure Mix_PauseMusic;
+cdecl; external {$IFDEF __GPC__}name 'Mix_PauseMusic'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_PauseMusic}
+
+procedure Mix_ResumeMusic;
+cdecl; external {$IFDEF __GPC__}name 'Mix_ResumeMusic'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_ResumeMusic}
+
+procedure Mix_RewindMusic;
+cdecl; external {$IFDEF __GPC__}name 'Mix_RewindMusic'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_RewindMusic}
+
+function Mix_PausedMusic : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_PausedMusic'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_PausedMusic}
+
+{ Set the current position in the music stream.
+ This returns 0 if successful, or -1 if it failed or isn't implemented.
+ This function is only implemented for MOD music formats (set pattern
+ order number) and for OGG music (set position in seconds), at the
+ moment.
+}
+function Mix_SetMusicPosition( position : double ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_SetMusicPosition'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_SetMusicPosition}
+
+{ Check the status of a specific channel.
+ If the specified channel is -1, check all channels.
+}
+function Mix_Playing( channel : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_Playing'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_Playing}
+
+function Mix_PlayingMusic : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_PlayingMusic'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_PlayingMusic}
+
+{ Stop music and set external music playback command }
+function Mix_SetMusicCMD( const command : PChar ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_SetMusicCMD'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_SetMusicCMD}
+
+{ Synchro value is set by MikMod from modules while playing }
+function Mix_SetSynchroValue( value : integer ) : integer; overload;
+cdecl; external {$IFDEF __GPC__}name 'Mix_SetSynchroValue'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_SetSynchroValue}
+
+function Mix_GetSynchroValue : integer; overload;
+cdecl; external {$IFDEF __GPC__}name 'Mix_GetSynchroValue'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_SetSynchroValue}
+
+{
+ Get the Mix_Chunk currently associated with a mixer channel
+ Returns nil if it's an invalid channel, or there's no chunk associated.
+}
+function Mix_GetChunk( channel : integer ) : PMix_Chunk;
+cdecl; external {$IFDEF __GPC__}name 'Mix_GetChunk'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_GetChunk}
+
+{ Close the mixer, halting all playing audio }
+procedure Mix_CloseAudio;
+cdecl; external {$IFDEF __GPC__}name 'Mix_CloseAudio'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_CloseAudio}
+
+{ We'll use SDL for reporting errors }
+procedure Mix_SetError( fmt : PChar );
+
+function Mix_GetError : PChar;
+
+{------------------------------------------------------------------------------}
+{ initialization }
+{------------------------------------------------------------------------------}
+
+{------------------------------------------------------------------------------}
+
+implementation
+
+{$IFDEF __GPC__}
+ {$L 'sdl_mixer'} { link sdl_mixer.dll.a or libsdl_mixer.so or libsdl_mixer.a }
+{$ENDIF}
+
+procedure SDL_MIXER_VERSION( var X : TSDL_version );
+begin
+ X.major := SDL_MIXER_MAJOR_VERSION;
+ X.minor := SDL_MIXER_MINOR_VERSION;
+ X.patch := SDL_MIXER_PATCHLEVEL;
+end;
+
+function Mix_LoadWAV( filename : PChar ) : PMix_Chunk;
+begin
+ result := Mix_LoadWAV_RW( SDL_RWFromFile( filename, 'rb' ), 1 );
+end;
+
+function Mix_PlayChannel( channel : integer; chunk : PMix_Chunk; loops : integer ) : integer;
+begin
+ result := Mix_PlayChannelTimed( channel, chunk, loops, -1 );
+end;
+
+function Mix_FadeInChannel( channel : integer; chunk : PMix_Chunk; loops :
+ integer; ms : integer ) : integer;
+begin
+ result := Mix_FadeInChannelTimed( channel, chunk, loops, ms, -1 );
+end;
+
+procedure Mix_SetError( fmt : PChar );
+begin
+ SDL_SetError( fmt );
+end;
+
+function Mix_GetError : PChar;
+begin
+ result := SDL_GetError;
+end;
+
+end. \ No newline at end of file
diff --git a/packages/sdl/src/sdl_mixer_nosmpeg.pas b/packages/sdl/src/sdl_mixer_nosmpeg.pas
new file mode 100644
index 0000000000..e3a455b5bf
--- /dev/null
+++ b/packages/sdl/src/sdl_mixer_nosmpeg.pas
@@ -0,0 +1,967 @@
+unit sdl_mixer_nosmpeg;
+{******************************************************************************}
+{ Copy of SDL_Mixer without smpeg dependency and mp3 support }
+{******************************************************************************}
+
+{$I jedi-sdl.inc}
+
+interface
+
+uses
+{$IFDEF __GPC__}
+ gpc,
+{$ENDIF}
+ sdl;
+
+const
+{$IFDEF WINDOWS}
+ SDL_MixerLibName = 'SDL_mixer.dll';
+{$ENDIF}
+
+{$IFDEF UNIX}
+{$IFDEF DARWIN}
+ SDL_MixerLibName = 'libSDL_mixer-1.2.0.dylib';
+{$ELSE}
+ {$IFDEF FPC}
+ SDL_MixerLibName = 'libSDL_mixer.so';
+ {$ELSE}
+ SDL_MixerLibName = 'libSDL_mixer-1.2.so.0';
+ {$ENDIF}
+{$ENDIF}
+{$ENDIF}
+
+{$IFDEF MACOS}
+ SDL_MixerLibName = 'SDL_mixer';
+{$ENDIF}
+
+ {* Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL *}
+ SDL_MIXER_MAJOR_VERSION = 1;
+{$EXTERNALSYM MIX_MAJOR_VERSION}
+ SDL_MIXER_MINOR_VERSION = 2;
+{$EXTERNALSYM MIX_MINOR_VERSION}
+ SDL_MIXER_PATCHLEVEL = 7;
+{$EXTERNALSYM MIX_PATCHLEVEL}
+
+ // Backwards compatibility
+ MIX_MAJOR_VERSION = SDL_MIXER_MAJOR_VERSION;
+ MIX_MINOR_VERSION = SDL_MIXER_MINOR_VERSION;
+ MIX_PATCHLEVEL = SDL_MIXER_PATCHLEVEL;
+
+ // SDL_Mixer.h constants
+ { The default mixer has 8 simultaneous mixing channels }
+{$IFNDEF MIX_CHANNELS}
+ MIX_CHANNELS = 8;
+{$ENDIF}
+{$EXTERNALSYM MIX_CHANNELS}
+ { Good default values for a PC soundcard }
+ MIX_DEFAULT_FREQUENCY = 22050;
+{$EXTERNALSYM MIX_DEFAULT_FREQUENCY}
+
+{$IFDEF IA32}
+ MIX_DEFAULT_FORMAT = AUDIO_S16LSB;
+{$ELSE}
+ MIX_DEFAULT_FORMAT = AUDIO_S16MSB;
+{$ENDIF}
+{$EXTERNALSYM MIX_DEFAULT_FORMAT}
+
+ MIX_DEFAULT_CHANNELS = 2;
+{$EXTERNALSYM MIX_DEFAULT_CHANNELS}
+ MIX_MAX_VOLUME = 128; { Volume of a chunk }
+{$EXTERNALSYM MIX_MAX_VOLUME}
+
+ PATH_MAX = 255;
+
+ // mikmod.h constants
+ {*
+ * Library version
+ *}
+ LIBMIKMOD_VERSION_MAJOR = 3;
+ LIBMIKMOD_VERSION_MINOR = 1;
+ LIBMIKMOD_REVISION = 8;
+ LIBMIKMOD_VERSION = ( ( LIBMIKMOD_VERSION_MAJOR shl 16 ) or
+ ( LIBMIKMOD_VERSION_MINOR shl 8 ) or
+ ( LIBMIKMOD_REVISION ) );
+
+type
+ //music_cmd.h types
+ PMusicCMD = ^TMusicCMD;
+ TMusicCMD = record
+ filename : array[ 0..PATH_MAX - 1 ] of char;
+ cmd : array[ 0..PATH_MAX - 1 ] of char;
+ pid : TSYS_ThreadHandle;
+ end;
+
+ //wavestream.h types
+ PWAVStream = ^TWAVStream;
+ TWAVStream = record
+ wavefp : Pointer;
+ start : longint;
+ stop : longint;
+ cvt : TSDL_AudioCVT;
+ end;
+
+ //playmidi.h types
+ PMidiEvent = ^TMidiEvent;
+ TMidiEvent = record
+ time : Longint;
+ channel : uint8;
+ type_ : uint8;
+ a : uint8;
+ b : uint8;
+ end;
+
+ PMidiSong = ^TMidiSong;
+ TMidiSong = record
+ samples : Longint;
+ events : PMidiEvent;
+ end;
+
+ //music_ogg.h types
+ POGG_Music = ^TOGG_Music;
+ TOGG_Music = record
+ playing : integer;
+ volume : integer;
+ //vf: OggVorbis_File;
+ section : integer;
+ cvt : TSDL_AudioCVT;
+ len_available : integer;
+ snd_available : PUint8;
+ end;
+
+ // mikmod.h types
+ {*
+ * Error codes
+ *}
+ TErrorEnum = (
+ MMERR_OPENING_FILE,
+ MMERR_OUT_OF_MEMORY,
+ MMERR_DYNAMIC_LINKING,
+ MMERR_SAMPLE_TOO_BIG,
+ MMERR_OUT_OF_HANDLES,
+ MMERR_UNKNOWN_WAVE_TYPE,
+ MMERR_LOADING_PATTERN,
+ MMERR_LOADING_TRACK,
+ MMERR_LOADING_HEADER,
+ MMERR_LOADING_SAMPLEINFO,
+ MMERR_NOT_A_MODULE,
+ MMERR_NOT_A_STREAM,
+ MMERR_MED_SYNTHSAMPLES,
+ MMERR_ITPACK_INVALID_DATA,
+ MMERR_DETECTING_DEVICE,
+ MMERR_INVALID_DEVICE,
+ MMERR_INITIALIZING_MIXER,
+ MMERR_OPENING_AUDIO,
+ MMERR_8BIT_ONLY,
+ MMERR_16BIT_ONLY,
+ MMERR_STEREO_ONLY,
+ MMERR_ULAW,
+ MMERR_NON_BLOCK,
+ MMERR_AF_AUDIO_PORT,
+ MMERR_AIX_CONFIG_INIT,
+ MMERR_AIX_CONFIG_CONTROL,
+ MMERR_AIX_CONFIG_START,
+ MMERR_GUS_SETTINGS,
+ MMERR_GUS_RESET,
+ MMERR_GUS_TIMER,
+ MMERR_HP_SETSAMPLESIZE,
+ MMERR_HP_SETSPEED,
+ MMERR_HP_CHANNELS,
+ MMERR_HP_AUDIO_OUTPUT,
+ MMERR_HP_AUDIO_DESC,
+ MMERR_HP_BUFFERSIZE,
+ MMERR_OSS_SETFRAGMENT,
+ MMERR_OSS_SETSAMPLESIZE,
+ MMERR_OSS_SETSTEREO,
+ MMERR_OSS_SETSPEED,
+ MMERR_SGI_SPEED,
+ MMERR_SGI_16BIT,
+ MMERR_SGI_8BIT,
+ MMERR_SGI_STEREO,
+ MMERR_SGI_MONO,
+ MMERR_SUN_INIT,
+ MMERR_OS2_MIXSETUP,
+ MMERR_OS2_SEMAPHORE,
+ MMERR_OS2_TIMER,
+ MMERR_OS2_THREAD,
+ MMERR_DS_PRIORITY,
+ MMERR_DS_BUFFER,
+ MMERR_DS_FORMAT,
+ MMERR_DS_NOTIFY,
+ MMERR_DS_EVENT,
+ MMERR_DS_THREAD,
+ MMERR_DS_UPDATE,
+ MMERR_WINMM_HANDLE,
+ MMERR_WINMM_ALLOCATED,
+ MMERR_WINMM_DEVICEID,
+ MMERR_WINMM_FORMAT,
+ MMERR_WINMM_UNKNOWN,
+ MMERR_MAC_SPEED,
+ MMERR_MAC_START,
+ MMERR_MAX
+ );
+
+ PMODULE = ^TMODULE;
+ TMODULE = record
+ (* general module information *)
+ //CHAR* songname; (* name of the song *)
+ //CHAR* modtype; (* string type of module loaded *)
+ //CHAR* comment; (* module comments *)
+ //UWORD flags; (* See module flags above *)
+ //UBYTE numchn; (* number of module channels *)
+ //UBYTE numvoices; (* max # voices used for full NNA playback *)
+ //UWORD numpos; (* number of positions in this song *)
+ //UWORD numpat; (* number of patterns in this song *)
+ //UWORD numins; (* number of instruments *)
+ //UWORD numsmp; (* number of samples *)
+ //type = record INSTRUMENT* instruments; (* all instruments *)
+ //type = record SAMPLE* samples; (* all samples *)
+ //UBYTE realchn; (* real number of channels used *)
+ //UBYTE totalchn; (* total number of channels used (incl NNAs) *)
+ (* playback settings *)
+ //UWORD reppos; (* restart position *)
+ //UBYTE initspeed; (* initial song speed *)
+ //UWORD inittempo; (* initial song tempo *)
+ //UBYTE initvolume; (* initial global volume (0 - 128) *)
+ //UWORD panning : array[ 0..64- 1 ] of ; (* 64 panning positions *)
+ //UBYTE chanvol : array[ 0..64- 1 ] of ; (* 64 channel positions *)
+ //UWORD bpm; (* current beats-per-minute speed *)
+ //UWORD sngspd; (* current song speed *)
+ //SWORD volume; (* song volume (0-128) (or user volume) *)
+ //BOOL extspd; (* extended speed flag (default enabled) *)
+ //BOOL panflag; (* panning flag (default enabled) *)
+ //BOOL wrap; (* wrap module ? (default disabled) *)
+ //BOOL loop; (* allow module to loop ? (default enabled) *)
+ //BOOL fadeout; (* volume fade out during last pattern *)
+ //UWORD patpos; (* current row number *)
+ //SWORD sngpos; (* current song position *)
+ //ULONG sngtime; (* current song time in 2^-10 seconds *)
+ //SWORD relspd; (* relative speed factor *)
+ (* internal module representation *)
+ //UWORD numtrk; (* number of tracks *)
+ //UBYTE** tracks; (* array of numtrk pointers to tracks *)
+ //UWORD* patterns; (* array of Patterns *)
+ //UWORD* pattrows; (* array of number of rows for each pattern *)
+ //UWORD* positions; (* all positions *)
+ //BOOL forbid; (* if true, no player updatenot *)
+ //UWORD numrow; (* number of rows on current pattern *)
+ //UWORD vbtick; (* tick counter (counts from 0 to sngspd) *)
+ //UWORD sngremainder;(* used for song time computation *)
+ //type = record MP_CONTROL* control; (* Effects Channel info (size pf.numchn) *)
+ //type = record MP_VOICE* voice; (* Audio Voice information (size md_numchn) *)
+ //UBYTE globalslide; (* global volume slide rate *)
+ //UBYTE pat_repcrazy;(* module has just looped to position -1 *)
+ //UWORD patbrk; (* position where to start a new pattern *)
+ //UBYTE patdly; (* patterndelay counter (command memory) *)
+ //UBYTE patdly2; (* patterndelay counter (real one) *)
+ //SWORD posjmp; (* flag to indicate a jump is needed... *)
+ end;
+
+ PUNIMOD = ^TUNIMOD;
+ TUNIMOD = TMODULE;
+
+ //SDL_mixer.h types
+ { The internal format for an audio chunk }
+ PMix_Chunk = ^TMix_Chunk;
+ TMix_Chunk = record
+ allocated : integer;
+ abuf : PUint8;
+ alen : Uint32;
+ volume : Uint8; { Per-sample volume, 0-128 }
+ end;
+ Mix_Chunk = TMix_Chunk;
+
+ { The different fading types supported }
+ TMix_Fading = (
+ MIX_NO_FADING,
+ MIX_FADING_OUT,
+ MIX_FADING_IN
+ );
+ Mix_Fading = TMix_Fading;
+
+ TMix_MusicType = (
+ MUS_NONE,
+ MUS_CMD,
+ MUS_WAV,
+ MUS_MOD,
+ MUS_MID,
+ MUS_OGG
+ );
+ Mix_MusicType = TMix_MusicType;
+
+ TMusicUnion = record
+ case Byte of
+ 0 : ( cmd : PMusicCMD );
+ 1 : ( wave : PWAVStream );
+ 2 : ( module : PUNIMOD );
+ 3 : ( midi : TMidiSong );
+ 4 : ( ogg : POGG_music );
+ end;
+
+ P_Mix_Music = ^T_Mix_Music;
+ T_Mix_Music = record
+ type_ : TMix_MusicType;
+ data : TMusicUnion;
+ fading : TMix_Fading;
+ fade_volume : integer;
+ fade_step : integer;
+ fade_steps : integer;
+ error : integer;
+ end;
+
+ { The internal format for a music chunk interpreted via mikmod }
+ PMix_Music = ^TMix_Music;
+ TMix_Music = T_Mix_Music;
+
+ {$IFNDEF __GPC__}
+ TMixFunction = function( udata : Pointer; stream : PUint8; len : integer ) : Pointer; cdecl;
+ {$ELSE}
+ TMixFunction = function( udata : Pointer; stream : PUint8; len : integer ) : Pointer;
+ {$ENDIF}
+
+{ This macro can be used to fill a version structure with the compile-time
+ version of the SDL_mixer library. }
+procedure SDL_MIXER_VERSION(var X: TSDL_Version);
+{$EXTERNALSYM SDL_MIXER_VERSION}
+
+{ This function gets the version of the dynamically linked SDL_mixer library.
+ It should NOT be used to fill a version structure, instead you should use the
+ SDL_MIXER_VERSION() macro. }
+function Mix_Linked_Version : PSDL_version;
+cdecl; external {$IFDEF __GPC__}name 'Mix_Linked_Version'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_Linked_Version}
+
+{ Open the mixer with a certain audio format }
+function Mix_OpenAudio( frequency : integer; format : Uint16; channels :
+ integer; chunksize : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_OpenAudio'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_OpenAudio}
+
+{ Dynamically change the number of channels managed by the mixer.
+ If decreasing the number of channels, the upper channels are
+ stopped.
+ This function returns the new number of allocated channels.
+ }
+function Mix_AllocateChannels( numchannels : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_AllocateChannels'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_AllocateChannels}
+
+{ Find out what the actual audio device parameters are.
+ This function returns 1 if the audio has been opened, 0 otherwise.
+ }
+function Mix_QuerySpec( var frequency : integer; var format : Uint16; var channels : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_QuerySpec'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_QuerySpec}
+
+{ Load a wave file or a music (.mod .s3m .it .xm) file }
+function Mix_LoadWAV_RW( src : PSDL_RWops; freesrc : integer ) : PMix_Chunk;
+cdecl; external {$IFDEF __GPC__}name 'Mix_LoadWAV_RW'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_LoadWAV_RW}
+
+function Mix_LoadWAV( filename : PChar ) : PMix_Chunk;
+
+function Mix_LoadMUS( const filename : PChar ) : PMix_Music;
+cdecl; external {$IFDEF __GPC__}name 'Mix_LoadMUS'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_LoadMUS}
+
+(*#if 0 { This hasn't been hooked into music.c yet }
+{ Load a music file from an SDL_RWop object (MikMod-specific currently)
+ Matt Campbell (matt@campbellhome.dhs.org) April 2000 }
+function Mix_LoadMUS_RW(SDL_RWops *rw) : PMix_Music; cdecl;
+#endif*)
+
+{ Load a wave file of the mixer format from a memory buffer }
+function Mix_QuickLoad_WAV( mem : PUint8 ) : PMix_Chunk;
+cdecl; external {$IFDEF __GPC__}name 'Mix_QuickLoad_WAV'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_QuickLoad_WAV}
+
+{ Free an audio chunk previously loaded }
+procedure Mix_FreeChunk( chunk : PMix_Chunk );
+cdecl; external {$IFDEF __GPC__}name 'Mix_FreeChunk'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_FreeChunk}
+
+procedure Mix_FreeMusic( music : PMix_Music );
+cdecl; external {$IFDEF __GPC__}name 'Mix_FreeMusic'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_FreeMusic}
+
+{ Find out the music format of a mixer music, or the currently playing
+ music, if 'music' is NULL.}
+function Mix_GetMusicType( music : PMix_Music ) : TMix_MusicType;
+cdecl; external {$IFDEF __GPC__}name 'Mix_GetMusicType'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_GetMusicType}
+
+{ Set a function that is called after all mixing is performed.
+ This can be used to provide real-time visual display of the audio stream
+ or add a custom mixer filter for the stream data.
+}
+procedure Mix_SetPostMix( mix_func : TMixFunction; arg : Pointer );
+cdecl; external {$IFDEF __GPC__}name 'Mix_SetPostMix'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_SetPostMix}
+
+{ Add your own music player or additional mixer function.
+ If 'mix_func' is NULL, the default music player is re-enabled.
+ }
+procedure Mix_HookMusic( mix_func : TMixFunction; arg : Pointer );
+ cdecl; external {$IFDEF __GPC__}name 'Mix_HookMusic'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_HookMusic}
+
+{ Add your own callback when the music has finished playing.
+ }
+procedure Mix_HookMusicFinished( music_finished : Pointer );
+cdecl; external {$IFDEF __GPC__}name 'Mix_HookMusicFinished'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_HookMusicFinished}
+
+{ Get a pointer to the user data for the current music hook }
+function Mix_GetMusicHookData : Pointer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_GetMusicHookData'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_GetMusicHookData}
+
+{* Add your own callback when a channel has finished playing. NULL
+ * to disable callback.*}
+type
+ {$IFNDEF __GPC__}
+ TChannel_finished = procedure( channel: Integer ); cdecl;
+ {$ELSE}
+ TChannel_finished = procedure( channel: Integer );
+ {$ENDIF}
+
+procedure Mix_ChannelFinished( channel_finished : TChannel_finished );
+cdecl; external {$IFDEF __GPC__}name 'Mix_ChannelFinished'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_ChannelFinished}
+
+const
+ MIX_CHANNEL_POST = -2;
+
+ {* This is the format of a special effect callback:
+ *
+ * myeffect(int chan, void *stream, int len, void *udata);
+ *
+ * (chan) is the channel number that your effect is affecting. (stream) is
+ * the buffer of data to work upon. (len) is the size of (stream), and
+ * (udata) is a user-defined bit of data, which you pass as the last arg of
+ * Mix_RegisterEffect(), and is passed back unmolested to your callback.
+ * Your effect changes the contents of (stream) based on whatever parameters
+ * are significant, or just leaves it be, if you prefer. You can do whatever
+ * you like to the buffer, though, and it will continue in its changed state
+ * down the mixing pipeline, through any other effect functions, then finally
+ * to be mixed with the rest of the channels and music for the final output
+ * stream.
+ *}
+type
+ {$IFNDEF __GPC__}
+ TMix_EffectFunc = function( chan : integer; stream : Pointer; len : integer; udata : Pointer ) : Pointer; cdecl;
+ {$ELSE}
+ TMix_EffectFunc = function( chan : integer; stream : Pointer; len : integer; udata : Pointer ) : Pointer;
+ {$ENDIF}
+ {*
+ * This is a callback that signifies that a channel has finished all its
+ * loops and has completed playback. This gets called if the buffer
+ * plays out normally, or if you call Mix_HaltChannel(), implicitly stop
+ * a channel via Mix_AllocateChannels(), or unregister a callback while
+ * it's still playing.
+ *}
+ {$IFNDEF __GPC__}
+ TMix_EffectDone = function( chan : integer; udata : Pointer ) : Pointer; cdecl;
+ {$ELSE}
+ TMix_EffectDone = function( chan : integer; udata : Pointer ) : Pointer;
+ {$ENDIF}
+ {* Register a special effect function. At mixing time, the channel data is
+ * copied into a buffer and passed through each registered effect function.
+ * After it passes through all the functions, it is mixed into the final
+ * output stream. The copy to buffer is performed once, then each effect
+ * function performs on the output of the previous effect. Understand that
+ * this extra copy to a buffer is not performed if there are no effects
+ * registered for a given chunk, which saves CPU cycles, and any given
+ * effect will be extra cycles, too, so it is crucial that your code run
+ * fast. Also note that the data that your function is given is in the
+ * format of the sound device, and not the format you gave to Mix_OpenAudio(),
+ * although they may in reality be the same. This is an unfortunate but
+ * necessary speed concern. Use Mix_QuerySpec() to determine if you can
+ * handle the data before you register your effect, and take appropriate
+ * actions.
+ * You may also specify a callback (Mix_EffectDone_t) that is called when
+ * the channel finishes playing. This gives you a more fine-grained control
+ * than Mix_ChannelFinished(), in case you need to free effect-specific
+ * resources, etc. If you don't need this, you can specify NULL.
+ * You may set the callbacks before or after calling Mix_PlayChannel().
+ * Things like Mix_SetPanning() are just internal special effect functions,
+ * so if you are using that, you've already incurred the overhead of a copy
+ * to a separate buffer, and that these effects will be in the queue with
+ * any functions you've registered. The list of registered effects for a
+ * channel is reset when a chunk finishes playing, so you need to explicitly
+ * set them with each call to Mix_PlayChannel*().
+ * You may also register a special effect function that is to be run after
+ * final mixing occurs. The rules for these callbacks are identical to those
+ * in Mix_RegisterEffect, but they are run after all the channels and the
+ * music have been mixed into a single stream, whereas channel-specific
+ * effects run on a given channel before any other mixing occurs. These
+ * global effect callbacks are call "posteffects". Posteffects only have
+ * their Mix_EffectDone_t function called when they are unregistered (since
+ * the main output stream is never "done" in the same sense as a channel).
+ * You must unregister them manually when you've had enough. Your callback
+ * will be told that the channel being mixed is (MIX_CHANNEL_POST) if the
+ * processing is considered a posteffect.
+ *
+ * After all these effects have finished processing, the callback registered
+ * through Mix_SetPostMix() runs, and then the stream goes to the audio
+ * device.
+ *
+ * returns zero if error (no such channel), nonzero if added.
+ * Error messages can be retrieved from Mix_GetError().
+ *}
+function Mix_RegisterEffect( chan : integer; f : TMix_EffectFunc; d : TMix_EffectDone; arg : Pointer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_RegisterEffect'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_RegisterEffect}
+
+{* You may not need to call this explicitly, unless you need to stop an
+ * effect from processing in the middle of a chunk's playback.
+ * Posteffects are never implicitly unregistered as they are for channels,
+ * but they may be explicitly unregistered through this function by
+ * specifying MIX_CHANNEL_POST for a channel.
+ * returns zero if error (no such channel or effect), nonzero if removed.
+ * Error messages can be retrieved from Mix_GetError().
+ *}
+function Mix_UnregisterEffect( channel : integer; f : TMix_EffectFunc ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_UnregisterEffect'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_UnregisterEffect}
+
+ {* You may not need to call this explicitly, unless you need to stop all
+ * effects from processing in the middle of a chunk's playback. Note that
+ * this will also shut off some internal effect processing, since
+ * Mix_SetPanning( ) and others may use this API under the hood.This is
+ * called internally when a channel completes playback.
+ * Posteffects are never implicitly unregistered as they are for channels,
+ * but they may be explicitly unregistered through this function by
+ * specifying MIX_CHANNEL_POST for a channel.
+ * returns zero if error( no such channel ), nonzero if all effects removed.
+ * Error messages can be retrieved from Mix_GetError( ).
+ *}
+function Mix_UnregisterAllEffects( channel : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_UnregisterAllEffects'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_UnregisterAllEffects}
+
+const
+ MIX_EFFECTSMAXSPEED = 'MIX_EFFECTSMAXSPEED';
+
+ {*
+ * These are the internally - defined mixing effects.They use the same API that
+ * effects defined in the application use, but are provided here as a
+ * convenience.Some effects can reduce their quality or use more memory in
+ * the name of speed; to enable this, make sure the environment variable
+ * MIX_EFFECTSMAXSPEED( see above ) is defined before you call
+ * Mix_OpenAudio( ).
+ * }
+
+ {* set the panning of a channel.The left and right channels are specified
+ * as integers between 0 and 255, quietest to loudest, respectively.
+ *
+ * Technically, this is just individual volume control for a sample with
+ * two( stereo )channels, so it can be used for more than just panning.
+ * if you want real panning, call it like this :
+ *
+ * Mix_SetPanning( channel, left, 255 - left );
+ *
+ * ...which isn't so hard.
+ *
+ * Setting( channel ) to MIX_CHANNEL_POST registers this as a posteffect, and
+ * the panning will be done to the final mixed stream before passing it on
+ * to the audio device.
+ *
+ * This uses the Mix_RegisterEffect( )API internally, and returns without
+ * registering the effect function if the audio device is not configured
+ * for stereo output.Setting both( left ) and ( right ) to 255 causes this
+ * effect to be unregistered, since that is the data's normal state.
+ *
+ * returns zero if error( no such channel or Mix_RegisterEffect( )fails ),
+ * nonzero if panning effect enabled.Note that an audio device in mono
+ * mode is a no - op, but this call will return successful in that case .
+ * Error messages can be retrieved from Mix_GetError( ).
+ * }
+ function Mix_SetPanning( channel : integer; left : Uint8; right : Uint8 ) : integer;
+ cdecl; external {$IFDEF __GPC__}name 'Mix_SetPanning'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+ {$EXTERNALSYM Mix_SetPanning}
+
+ { * set the position ofa channel.( angle ) is an integer from 0 to 360, that
+ * specifies the location of the sound in relation to the listener.( angle )
+ * will be reduced as neccesary( 540 becomes 180 degrees, -100 becomes 260 ).
+ * Angle 0 is due north, and rotates clockwise as the value increases.
+ * for efficiency, the precision of this effect may be limited( angles 1
+ * through 7 might all produce the same effect, 8 through 15 are equal, etc ).
+ * ( distance ) is an integer between 0 and 255 that specifies the space
+ * between the sound and the listener.The larger the number, the further
+ * away the sound is .Using 255 does not guarantee that the channel will be
+ * culled from the mixing process or be completely silent.For efficiency,
+ * the precision of this effect may be limited( distance 0 through 5 might
+ * all produce the same effect, 6 through 10 are equal, etc ).Setting( angle )
+ * and ( distance ) to 0 unregisters this effect, since the data would be
+ * unchanged.
+ *
+ * if you need more precise positional audio, consider using OpenAL for
+ * spatialized effects instead of SDL_mixer.This is only meant to be a
+ * basic effect for simple "3D" games.
+ *
+ * if the audio device is configured for mono output, then you won't get
+ * any effectiveness from the angle; however, distance attenuation on the
+ * channel will still occur.While this effect will function with stereo
+ * voices, it makes more sense to use voices with only one channel of sound,
+ * so when they are mixed through this effect, the positioning will sound
+ * correct.You can convert them to mono through SDL before giving them to
+ * the mixer in the first place if you like.
+ *
+ * Setting( channel ) to MIX_CHANNEL_POST registers this as a posteffect, and
+ * the positioning will be done to the final mixed stream before passing it
+ * on to the audio device.
+ *
+ * This is a convenience wrapper over Mix_SetDistance( ) and Mix_SetPanning( ).
+ *
+ * returns zero if error( no such channel or Mix_RegisterEffect( )fails ),
+ * nonzero if position effect is enabled.
+ * Error messages can be retrieved from Mix_GetError( ).
+ * }
+ function Mix_SetPosition( channel :integer; angle : Sint16; distance : Uint8 ) : integer;
+ cdecl; external {$IFDEF __GPC__}name 'Mix_SetPosition'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+ {$EXTERNALSYM Mix_SetPosition}
+
+ {* set the "distance" of a channel.( distance ) is an integer from 0 to 255
+ * that specifies the location of the sound in relation to the listener.
+ * Distance 0 is overlapping the listener, and 255 is as far away as possible
+ * A distance of 255 does not guarantee silence; in such a case , you might
+ * want to try changing the chunk's volume, or just cull the sample from the
+ * mixing process with Mix_HaltChannel( ).
+ * for efficiency, the precision of this effect may be limited( distances 1
+ * through 7 might all produce the same effect, 8 through 15 are equal, etc ).
+ * ( distance ) is an integer between 0 and 255 that specifies the space
+ * between the sound and the listener.The larger the number, the further
+ * away the sound is .
+ * Setting( distance ) to 0 unregisters this effect, since the data would be
+ * unchanged.
+ * if you need more precise positional audio, consider using OpenAL for
+ * spatialized effects instead of SDL_mixer.This is only meant to be a
+ * basic effect for simple "3D" games.
+ *
+ * Setting( channel ) to MIX_CHANNEL_POST registers this as a posteffect, and
+ * the distance attenuation will be done to the final mixed stream before
+ * passing it on to the audio device.
+ *
+ * This uses the Mix_RegisterEffect( )API internally.
+ *
+ * returns zero if error( no such channel or Mix_RegisterEffect( )fails ),
+ * nonzero if position effect is enabled.
+ * Error messages can be retrieved from Mix_GetError( ).
+ * }
+ function Mix_SetDistance( channel : integer; distance : Uint8 ) : integer;
+ cdecl; external {$IFDEF __GPC__}name 'Mix_SetDistance'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+ {$EXTERNALSYM Mix_SetDistance}
+ { *
+ * !!! FIXME : Haven't implemented, since the effect goes past the
+ * end of the sound buffer.Will have to think about this.
+ * - -ryan.
+ * /
+ { if 0
+ { * Causes an echo effect to be mixed into a sound.( echo ) is the amount
+ * of echo to mix.0 is no echo, 255 is infinite( and probably not
+ * what you want ).
+ *
+ * Setting( channel ) to MIX_CHANNEL_POST registers this as a posteffect, and
+ * the reverbing will be done to the final mixed stream before passing it on
+ * to the audio device.
+ *
+ * This uses the Mix_RegisterEffect( )API internally.If you specify an echo
+ * of zero, the effect is unregistered, as the data is already in that state.
+ *
+ * returns zero if error( no such channel or Mix_RegisterEffect( )fails ),
+ * nonzero if reversing effect is enabled.
+ * Error messages can be retrieved from Mix_GetError( ).
+ *
+ extern no_parse_DECLSPEC int Mix_SetReverb( int channel, Uint8 echo );
+ #E ndif}
+ { * Causes a channel to reverse its stereo.This is handy if the user has his
+ * speakers hooked up backwards, or you would like to have a minor bit of
+ * psychedelia in your sound code. : )Calling this function with ( flip )
+ * set to non - zero reverses the chunks's usual channels. If (flip) is zero,
+ * the effect is unregistered.
+ *
+ * This uses the Mix_RegisterEffect( )API internally, and thus is probably
+ * more CPU intensive than having the user just plug in his speakers
+ * correctly.Mix_SetReverseStereo( )returns without registering the effect
+ * function if the audio device is not configured for stereo output.
+ *
+ * if you specify MIX_CHANNEL_POST for ( channel ), then this the effect is used
+ * on the final mixed stream before sending it on to the audio device( a
+ * posteffect ).
+ *
+ * returns zero if error( no such channel or Mix_RegisterEffect( )fails ),
+ * nonzero if reversing effect is enabled.Note that an audio device in mono
+ * mode is a no - op, but this call will return successful in that case .
+ * Error messages can be retrieved from Mix_GetError( ).
+ * }
+ function Mix_SetReverseStereo( channel : integer; flip : integer ) : integer;
+ cdecl; external {$IFDEF __GPC__}name 'Mix_SetReverseStereo'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+ {$EXTERNALSYM Mix_SetReverseStereo}
+ { end of effects API. - -ryan. *}
+
+{ Reserve the first channels (0 -> n-1) for the application, i.e. don't allocate
+ them dynamically to the next sample if requested with a -1 value below.
+ Returns the number of reserved channels.
+ }
+function Mix_ReserveChannels( num : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_ReserveChannels'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_ReserveChannels}
+
+{ Channel grouping functions }
+
+{ Attach a tag to a channel. A tag can be assigned to several mixer
+ channels, to form groups of channels.
+ If 'tag' is -1, the tag is removed (actually -1 is the tag used to
+ represent the group of all the channels).
+ Returns true if everything was OK.
+ }
+function Mix_GroupChannel( which : integer; tag : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_GroupChannel'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_GroupChannel}
+
+{ Assign several consecutive channels to a group }
+function Mix_GroupChannels( from : integer; to_ : integer; tag : integer ) :
+integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_GroupChannels'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_GroupChannels}
+
+{ Finds the first available channel in a group of channels }
+function Mix_GroupAvailable( tag : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_GroupAvailable'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_GroupAvailable}
+
+{ Returns the number of channels in a group. This is also a subtle
+ way to get the total number of channels when 'tag' is -1
+ }
+function Mix_GroupCount( tag : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_GroupCount'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_GroupCount}
+
+{ Finds the "oldest" sample playing in a group of channels }
+function Mix_GroupOldest( tag : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_GroupOldest'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_GroupOldest}
+
+{ Finds the "most recent" (i.e. last) sample playing in a group of channels }
+function Mix_GroupNewer( tag : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_GroupNewer'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_GroupNewer}
+
+{ The same as above, but the sound is played at most 'ticks' milliseconds }
+function Mix_PlayChannelTimed( channel : integer; chunk : PMix_Chunk; loops : integer; ticks : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_PlayChannelTimed'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_PlayChannelTimed}
+
+{ Play an audio chunk on a specific channel.
+ If the specified channel is -1, play on the first free channel.
+ If 'loops' is greater than zero, loop the sound that many times.
+ If 'loops' is -1, loop inifinitely (~65000 times).
+ Returns which channel was used to play the sound.
+}
+function Mix_PlayChannel( channel : integer; chunk : PMix_Chunk; loops : integer ) : integer;
+
+function Mix_PlayMusic( music : PMix_Music; loops : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_PlayMusic'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_PlayMusic}
+
+{ Fade in music or a channel over "ms" milliseconds, same semantics as the "Play" functions }
+function Mix_FadeInMusic( music : PMix_Music; loops : integer; ms : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_FadeInMusic'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_FadeInMusic}
+
+function Mix_FadeInChannelTimed( channel : integer; chunk : PMix_Chunk; loops : integer; ms : integer; ticks : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_FadeInChannelTimed'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_FadeInChannelTimed}
+
+function Mix_FadeInChannel( channel : integer; chunk : PMix_Chunk; loops : integer; ms : integer ) : integer;
+
+{ Set the volume in the range of 0-128 of a specific channel or chunk.
+ If the specified channel is -1, set volume for all channels.
+ Returns the original volume.
+ If the specified volume is -1, just return the current volume.
+}
+function Mix_Volume( channel : integer; volume : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_Volume'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_Volume}
+
+function Mix_VolumeChunk( chunk : PMix_Chunk; volume : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_VolumeChunk'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_VolumeChunk}
+
+function Mix_VolumeMusic( volume : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_VolumeMusic'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_VolumeMusic}
+
+{ Halt playing of a particular channel }
+function Mix_HaltChannel( channel : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_HaltChannel'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_HaltChannel}
+
+function Mix_HaltGroup( tag : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_HaltGroup'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_HaltGroup}
+
+function Mix_HaltMusic : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_HaltMusic'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_HaltMusic}
+
+{ Change the expiration delay for a particular channel.
+ The sample will stop playing after the 'ticks' milliseconds have elapsed,
+ or remove the expiration if 'ticks' is -1
+}
+function Mix_ExpireChannel( channel : integer; ticks : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_ExpireChannel'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_ExpireChannel}
+
+{ Halt a channel, fading it out progressively till it's silent
+ The ms parameter indicates the number of milliseconds the fading
+ will take.
+ }
+function Mix_FadeOutChannel( which : integer; ms : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_FadeOutChannel'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_FadeOutChannel}
+function Mix_FadeOutGroup( tag : integer; ms : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_FadeOutGroup'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_FadeOutGroup}
+function Mix_FadeOutMusic( ms : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_FadeOutMusic'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_FadeOutMusic}
+
+{ Query the fading status of a channel }
+function Mix_FadingMusic : TMix_Fading;
+cdecl; external {$IFDEF __GPC__}name 'Mix_FadingMusic'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_FadingMusic}
+
+function Mix_FadingChannel( which : integer ) : TMix_Fading;
+cdecl; external {$IFDEF __GPC__}name 'Mix_FadingChannel'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_FadingChannel}
+
+{ Pause/Resume a particular channel }
+procedure Mix_Pause( channel : integer );
+cdecl; external {$IFDEF __GPC__}name 'Mix_Pause'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_Pause}
+
+procedure Mix_Resume( channel : integer );
+cdecl; external {$IFDEF __GPC__}name 'Mix_Resume'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_Resume}
+
+function Mix_Paused( channel : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_Paused'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_Paused}
+
+{ Pause/Resume the music stream }
+procedure Mix_PauseMusic;
+cdecl; external {$IFDEF __GPC__}name 'Mix_PauseMusic'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_PauseMusic}
+
+procedure Mix_ResumeMusic;
+cdecl; external {$IFDEF __GPC__}name 'Mix_ResumeMusic'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_ResumeMusic}
+
+procedure Mix_RewindMusic;
+cdecl; external {$IFDEF __GPC__}name 'Mix_RewindMusic'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_RewindMusic}
+
+function Mix_PausedMusic : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_PausedMusic'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_PausedMusic}
+
+{ Set the current position in the music stream.
+ This returns 0 if successful, or -1 if it failed or isn't implemented.
+ This function is only implemented for MOD music formats (set pattern
+ order number) and for OGG music (set position in seconds), at the
+ moment.
+}
+function Mix_SetMusicPosition( position : double ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_SetMusicPosition'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_SetMusicPosition}
+
+{ Check the status of a specific channel.
+ If the specified channel is -1, check all channels.
+}
+function Mix_Playing( channel : integer ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_Playing'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_Playing}
+
+function Mix_PlayingMusic : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_PlayingMusic'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_PlayingMusic}
+
+{ Stop music and set external music playback command }
+function Mix_SetMusicCMD( const command : PChar ) : integer;
+cdecl; external {$IFDEF __GPC__}name 'Mix_SetMusicCMD'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_SetMusicCMD}
+
+{ Synchro value is set by MikMod from modules while playing }
+function Mix_SetSynchroValue( value : integer ) : integer; overload;
+cdecl; external {$IFDEF __GPC__}name 'Mix_SetSynchroValue'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_SetSynchroValue}
+
+function Mix_GetSynchroValue : integer; overload;
+cdecl; external {$IFDEF __GPC__}name 'Mix_GetSynchroValue'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_SetSynchroValue}
+
+{
+ Get the Mix_Chunk currently associated with a mixer channel
+ Returns nil if it's an invalid channel, or there's no chunk associated.
+}
+function Mix_GetChunk( channel : integer ) : PMix_Chunk;
+cdecl; external {$IFDEF __GPC__}name 'Mix_GetChunk'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_GetChunk}
+
+{ Close the mixer, halting all playing audio }
+procedure Mix_CloseAudio;
+cdecl; external {$IFDEF __GPC__}name 'Mix_CloseAudio'{$ELSE} SDL_MixerLibName{$ENDIF __GPC__};
+{$EXTERNALSYM Mix_CloseAudio}
+
+{ We'll use SDL for reporting errors }
+procedure Mix_SetError( fmt : PChar );
+
+function Mix_GetError : PChar;
+
+{------------------------------------------------------------------------------}
+{ initialization }
+{------------------------------------------------------------------------------}
+
+{------------------------------------------------------------------------------}
+
+implementation
+
+{$IFDEF __GPC__}
+ {$L 'sdl_mixer'} { link sdl_mixer.dll.a or libsdl_mixer.so or libsdl_mixer.a }
+{$ENDIF}
+
+procedure SDL_MIXER_VERSION( var X : TSDL_version );
+begin
+ X.major := SDL_MIXER_MAJOR_VERSION;
+ X.minor := SDL_MIXER_MINOR_VERSION;
+ X.patch := SDL_MIXER_PATCHLEVEL;
+end;
+
+function Mix_LoadWAV( filename : PChar ) : PMix_Chunk;
+begin
+ result := Mix_LoadWAV_RW( SDL_RWFromFile( filename, 'rb' ), 1 );
+end;
+
+function Mix_PlayChannel( channel : integer; chunk : PMix_Chunk; loops : integer ) : integer;
+begin
+ result := Mix_PlayChannelTimed( channel, chunk, loops, -1 );
+end;
+
+function Mix_FadeInChannel( channel : integer; chunk : PMix_Chunk; loops :
+ integer; ms : integer ) : integer;
+begin
+ result := Mix_FadeInChannelTimed( channel, chunk, loops, ms, -1 );
+end;
+
+procedure Mix_SetError( fmt : PChar );
+begin
+ SDL_SetError( fmt );
+end;
+
+function Mix_GetError : PChar;
+begin
+ result := SDL_GetError;
+end;
+
+end.
diff --git a/packages/sdl/src/sdl_net.pas b/packages/sdl/src/sdl_net.pas
new file mode 100644
index 0000000000..3ddedd27b1
--- /dev/null
+++ b/packages/sdl/src/sdl_net.pas
@@ -0,0 +1,629 @@
+unit sdl_net;
+{******************************************************************************}
+{
+ $Id: sdl_net.pas,v 1.7 2005/01/01 02:14:21 savage Exp $
+
+}
+{ }
+{ Borland Delphi SDL_Net - A x-platform network library for use with SDL.}
+{ Conversion of the Simple DirectMedia Layer Network Headers }
+{ }
+{ Portions created by Sam Lantinga <slouken@devolution.com> are }
+{ Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga }
+{ 5635-34 Springhouse Dr. }
+{ Pleasanton, CA 94588 (USA) }
+{ }
+{ All Rights Reserved. }
+{ }
+{ The original files are : SDL_net.h }
+{ }
+{ The initial developer of this Pascal code was : }
+{ Dominqiue Louis <Dominique@SavageSoftware.com.au> }
+{ }
+{ Portions created by Dominqiue Louis are }
+{ Copyright (C) 2000 - 2001 Dominqiue Louis. }
+{ }
+{ }
+{ Contributor(s) }
+{ -------------- }
+{ Matthias Thoma <ma.thoma@gmx.de> }
+{ }
+{ Obtained through: }
+{ Joint Endeavour of Delphi Innovators ( Project JEDI ) }
+{ }
+{ You may retrieve the latest version of this file at the Project }
+{ JEDI home page, located at http://delphi-jedi.org }
+{ }
+{ The contents of this file are used with permission, subject to }
+{ the Mozilla Public License Version 1.1 (the "License"); you may }
+{ not use this file except in compliance with the License. You may }
+{ obtain a copy of the License at }
+{ http://www.mozilla.org/MPL/MPL-1.1.html }
+{ }
+{ Software distributed under the License is distributed on an }
+{ "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or }
+{ implied. See the License for the specific language governing }
+{ rights and limitations under the License. }
+{ }
+{ Description }
+{ ----------- }
+{ }
+{ }
+{ }
+{ }
+{ }
+{ }
+{ }
+{ Requires }
+{ -------- }
+{ SDL.pas somehere in your search path }
+{ }
+{ Programming Notes }
+{ ----------------- }
+{ }
+{ }
+{ }
+{ }
+{ Revision History }
+{ ---------------- }
+{ April 09 2001 - DL : Initial Translation }
+{ }
+{ April 03 2003 - DL : Added jedi-sdl.inc include file to support more }
+{ Pascal compilers. Initial support is now included }
+{ for GnuPascal, VirtualPascal, TMT and obviously }
+{ continue support for Delphi Kylix and FreePascal. }
+{ }
+{ April 24 2003 - DL : under instruction from Alexey Barkovoy, I have added}
+{ better TMT Pascal support and under instruction }
+{ from Prof. Abimbola Olowofoyeku (The African Chief),}
+{ I have added better Gnu Pascal support }
+{ }
+{ April 30 2003 - DL : under instruction from David Mears AKA }
+{ Jason Siletto, I have added FPC Linux support. }
+{ This was compiled with fpc 1.1, so remember to set }
+{ include file path. ie. -Fi/usr/share/fpcsrc/rtl/* }
+{ }
+{
+ $Log: sdl_net.pas,v $
+ Revision 1.7 2005/01/01 02:14:21 savage
+ Updated to v1.2.5
+
+ Revision 1.6 2004/08/14 22:54:30 savage
+ Updated so that Library name defines are correctly defined for MacOS X.
+
+ Revision 1.5 2004/05/10 14:10:04 savage
+ Initial MacOS X support. Fixed defines for MACOS ( Classic ) and DARWIN ( MacOS X ).
+
+ Revision 1.4 2004/04/13 09:32:08 savage
+ Changed Shared object names back to just the .so extension to avoid conflicts on various Linux/Unix distros. Therefore developers will need to create Symbolic links to the actual Share Objects if necessary.
+
+ Revision 1.3 2004/04/01 20:53:23 savage
+ Changed Linux Shared Object names so they reflect the Symbolic Links that are created when installing the RPMs from the SDL site.
+
+ Revision 1.2 2004/03/30 20:23:28 savage
+ Tidied up use of UNIX compiler directive.
+
+ Revision 1.1 2004/02/16 22:16:40 savage
+ v1.0 changes
+
+
+}
+{******************************************************************************}
+
+
+{$I jedi-sdl.inc}
+
+interface
+
+uses
+{$IFDEF __GPC__}
+ gpc,
+{$ENDIF}
+
+{$IFDEF windows}
+{$IFNDEF __GPC__}
+ Windows,
+{$ENDIF}
+{$ENDIF}
+ sdl;
+
+const
+{$IFDEF windows}
+ SDLNetLibName = 'SDL_net.dll';
+{$ENDIF}
+
+{$IFDEF UNIX}
+{$IFDEF DARWIN}
+ SDLNetLibName = 'libSDL_net.dylib';
+{$ELSE}
+ SDLNetLibName = 'libSDL_net.so';
+{$ENDIF}
+{$ENDIF}
+
+{$IFDEF MACOS}
+ SDLNetLibName = 'SDL_net';
+{$ENDIF}
+
+ {* Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL *}
+ SDL_NET_MAJOR_VERSION = 1;
+{$EXTERNALSYM SDL_NET_MAJOR_VERSION}
+ SDL_NET_MINOR_VERSION = 2;
+{$EXTERNALSYM SDL_NET_MINOR_VERSION}
+ SDL_NET_PATCHLEVEL = 5;
+{$EXTERNALSYM SDL_NET_PATCHLEVEL}
+
+ // SDL_Net.h constants
+ {* Resolve a host name and port to an IP address in network form.
+ If the function succeeds, it will return 0.
+ If the host couldn't be resolved, the host portion of the returned
+ address will be INADDR_NONE, and the function will return -1.
+ If 'host' is NULL, the resolved host will be set to INADDR_ANY.
+ *}
+ INADDR_ANY = $00000000;
+{$EXTERNALSYM INADDR_ANY}
+
+ INADDR_NONE = $FFFFFFFF;
+{$EXTERNALSYM INADDR_NONE}
+
+{***********************************************************************}
+{* UDP network API *}
+{***********************************************************************}
+{* The maximum channels on a a UDP socket *}
+ SDLNET_MAX_UDPCHANNELS = 32;
+{$EXTERNALSYM SDLNET_MAX_UDPCHANNELS}
+{* The maximum addresses bound to a single UDP socket channel *}
+ SDLNET_MAX_UDPADDRESSES = 4;
+{$EXTERNALSYM SDLNET_MAX_UDPADDRESSES}
+
+type
+ // SDL_net.h types
+ {***********************************************************************}
+ {* IPv4 hostname resolution API *}
+ {***********************************************************************}
+ PIPAddress = ^TIPAddress;
+ TIPAddress = record
+ host : Uint32; // 32-bit IPv4 host address */
+ port : Uint16; // 16-bit protocol port */
+ end;
+
+ {***********************************************************************}
+ {* TCP network API *}
+ {***********************************************************************}
+ PTCPSocket = ^TTCPSocket;
+ TTCPSocket = record
+ ready : integer;
+{$IFDEF windows}
+ channel : integer;
+{$ENDIF}
+{$IFDEF UNIX}
+ channel : integer;
+{$ENDIF}
+ remoteAddress : TIPaddress;
+ localAddress : TIPaddress;
+ sflag : integer;
+ end;
+
+ {***********************************************************************}
+ {* UDP network API *}
+ {***********************************************************************}
+ PUDP_Channel = ^TUDP_Channel;
+ TUDP_Channel = record
+ numbound : integer;
+ address : array[ 0..SDLNET_MAX_UDPADDRESSES - 1 ] of TIPAddress;
+ end;
+
+ PUDPSocket = ^TUDPSocket;
+ TUDPSocket = record
+ ready : integer;
+{$IFDEF windows}
+ channel : integer;
+{$ENDIF}
+{$IFDEF UNIX}
+ channel : integer;
+{$ENDIF}
+ address : TIPAddress;
+ binding : array[ 0..SDLNET_MAX_UDPCHANNELS - 1 ] of TUDP_Channel;
+ end;
+
+ PUDPpacket = ^TUDPpacket;
+ PPUDPpacket = ^PUDPpacket;
+ TUDPpacket = record
+ channel : integer; {* The src/dst channel of the packet *}
+ data : PUint8; {* The packet data *}
+ len : integer; {* The length of the packet data *}
+ maxlen : integer; {* The size of the data buffer *}
+ status : integer; {* packet status after sending *}
+ address : TIPAddress; {* The source/dest address of an incoming/outgoing packet *}
+ end;
+
+ {***********************************************************************}
+ {* Hooks for checking sockets for available data *}
+ {***********************************************************************}
+ PSDLNet_Socket = ^TSDLNet_Socket;
+ TSDLNet_Socket = record
+ ready : integer;
+{$IFDEF windows}
+ channel : integer;
+{$ENDIF}
+{$IFDEF UNIX}
+ channel : integer;
+{$ENDIF}
+ end;
+
+ PSDLNet_SocketSet = ^TSDLNet_SocketSet;
+ TSDLNet_SocketSet = record
+ numsockets : integer;
+ maxsockets : integer;
+ sockets : PSDLNet_Socket;
+ end;
+
+ {* Any network socket can be safely cast to this socket type *}
+ PSDLNet_GenericSocket = ^TSDLNet_GenericSocket;
+ TSDLNet_GenericSocket = record
+ ready : integer;
+ end;
+
+{ This macro can be used to fill a version structure with the compile-time
+ version of the SDL_net library. }
+procedure SDL_NET_VERSION( var X : TSDL_version );
+{$EXTERNALSYM SDL_NET_VERSION}
+
+{* Initialize/Cleanup the network API
+ SDL must be initialized before calls to functions in this library,
+ because this library uses utility functions from the SDL library.
+*}
+function SDLNet_Init : integer;
+cdecl; external{$IFDEF __GPC__}name 'SDLNet_Init'{$ELSE}SDLNetLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDLNet_Init}
+
+procedure SDLNet_Quit;
+cdecl; external{$IFDEF __GPC__}name 'SDLNet_Quit'{$ELSE}SDLNetLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDLNet_Quit}
+
+ {* Resolve a host name and port to an IP address in network form.
+ If the function succeeds, it will return 0.
+ If the host couldn't be resolved, the host portion of the returned
+ address will be INADDR_NONE, and the function will return -1.
+ If 'host' is NULL, the resolved host will be set to INADDR_ANY.
+ *}
+function SDLNet_ResolveHost( var address : TIPaddress; host : PCHar; port : Uint16 ) : integer;
+cdecl; external{$IFDEF __GPC__}name 'SDLNet_ResolveHost'{$ELSE}SDLNetLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDLNet_ResolveHost}
+
+{* Resolve an ip address to a host name in canonical form.
+ If the ip couldn't be resolved, this function returns NULL,
+ otherwise a pointer to a static buffer containing the hostname
+ is returned. Note that this function is not thread-safe.
+*}
+function SDLNet_ResolveIP( var ip : TIPaddress ) : PChar;
+cdecl; external{$IFDEF __GPC__}name 'SDLNet_ResolveIP'{$ELSE}SDLNetLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDLNet_ResolveIP}
+
+ {***********************************************************************}
+ {* TCP network API *}
+ {***********************************************************************}
+
+{* Open a TCP network socket
+ If ip.host is INADDR_NONE, this creates a local server socket on the
+ given port, otherwise a TCP connection to the remote host and port is
+ attempted. The address passed in should already be swapped to network
+ byte order (addresses returned from SDLNet_ResolveHost() are already
+ in the correct form).
+ The newly created socket is returned, or NULL if there was an error.
+*}
+function SDLNet_TCP_Open( var ip : TIPaddress ) : PTCPSocket;
+cdecl; external{$IFDEF __GPC__}name 'SDLNet_TCP_Open'{$ELSE}SDLNetLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDLNet_TCP_Open}
+
+{* Accept an incoming connection on the given server socket.
+ The newly created socket is returned, or NULL if there was an error.
+*}
+function SDLNet_TCP_Accept( server : PTCPsocket ) : PTCPSocket;
+cdecl; external{$IFDEF __GPC__}name 'SDLNet_TCP_Accept'{$ELSE}SDLNetLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDLNet_TCP_Accept}
+
+{* Get the IP address of the remote system associated with the socket.
+ If the socket is a server socket, this function returns NULL.
+*}
+function SDLNet_TCP_GetPeerAddress( sock : PTCPsocket ) : PIPAddress;
+cdecl; external{$IFDEF __GPC__}name 'SDLNet_TCP_GetPeerAddress'{$ELSE}SDLNetLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDLNet_TCP_GetPeerAddress}
+
+{* Send 'len' bytes of 'data' over the non-server socket 'sock'
+ This function returns the actual amount of data sent. If the return value
+ is less than the amount of data sent, then either the remote connection was
+ closed, or an unknown socket error occurred.
+*}
+function SDLNet_TCP_Send( sock : PTCPsocket; data : Pointer; len : integer ) : integer;
+cdecl; external{$IFDEF __GPC__}name 'SDLNet_TCP_Send'{$ELSE}SDLNetLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDLNet_TCP_Send}
+
+{* Receive up to 'maxlen' bytes of data over the non-server socket 'sock',
+ and store them in the buffer pointed to by 'data'.
+ This function returns the actual amount of data received. If the return
+ value is less than or equal to zero, then either the remote connection was
+ closed, or an unknown socket error occurred.
+*}
+function SDLNet_TCP_Recv( sock : PTCPsocket; data : Pointer; maxlen : integer ) : integer;
+cdecl; external{$IFDEF __GPC__}name 'SDLNet_TCP_Recv'{$ELSE}SDLNetLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDLNet_TCP_Recv}
+
+{* Close a TCP network socket *}
+procedure SDLNet_TCP_Close( sock : PTCPsocket );
+cdecl; external{$IFDEF __GPC__}name 'SDLNet_TCP_Close'{$ELSE}SDLNetLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDLNet_TCP_Close}
+
+
+ {***********************************************************************}
+ {* UDP network API *}
+ {***********************************************************************}
+
+ {* Allocate/resize/free a single UDP packet 'size' bytes long.
+ The new packet is returned, or NULL if the function ran out of memory.
+ *}
+function SDLNet_AllocPacket( size : integer ) : PUDPpacket;
+cdecl; external{$IFDEF __GPC__}name 'SDLNet_AllocPacket'{$ELSE}SDLNetLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDLNet_AllocPacket}
+
+function SDLNet_ResizePacket( packet : PUDPpacket; newsize : integer ) : integer;
+cdecl; external{$IFDEF __GPC__}name 'SDLNet_ResizePacket'{$ELSE}SDLNetLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDLNet_ResizePacket}
+
+procedure SDLNet_FreePacket( packet : PUDPpacket );
+cdecl; external{$IFDEF __GPC__}name 'SDLNet_FreePacket'{$ELSE}SDLNetLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDLNet_FreePacket}
+
+{* Allocate/Free a UDP packet vector (array of packets) of 'howmany' packets,
+ each 'size' bytes long.
+ A pointer to the first packet in the array is returned, or NULL if the
+ function ran out of memory.
+ *}
+function SDLNet_AllocPacketV( howmany : integer; size : integer ) : PUDPpacket;
+cdecl; external{$IFDEF __GPC__}name 'SDLNet_AllocPacketV'{$ELSE}SDLNetLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDLNet_AllocPacketV}
+
+procedure SDLNet_FreePacketV( packetV : PUDPpacket );
+cdecl; external{$IFDEF __GPC__}name 'SDLNet_FreePacketV'{$ELSE}SDLNetLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDLNet_FreePacketV}
+
+{* Open a UDP network socket
+ If 'port' is non-zero, the UDP socket is bound to a local port.
+ This allows other systems to send to this socket via a known port.
+*}
+function SDLNet_UDP_Open( port : Uint16 ) : PUDPsocket;
+cdecl; external{$IFDEF __GPC__}name 'SDLNet_UDP_Open'{$ELSE}SDLNetLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDLNet_UDP_Open}
+
+{* Bind the address 'address' to the requested channel on the UDP socket.
+ If the channel is -1, then the first unbound channel will be bound with
+ the given address as it's primary address.
+ If the channel is already bound, this new address will be added to the
+ list of valid source addresses for packets arriving on the channel.
+ If the channel is not already bound, then the address becomes the primary
+ address, to which all outbound packets on the channel are sent.
+ This function returns the channel which was bound, or -1 on error.
+*}
+function SDLNet_UDP_Bind( sock : PUDPsocket; channel : integer; var address : TIPaddress ) : integer;
+cdecl; external{$IFDEF __GPC__}name 'SDLNet_UDP_Bind'{$ELSE}SDLNetLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDLNet_UDP_Bind}
+
+{* Unbind all addresses from the given channel *}
+procedure SDLNet_UDP_Unbind( sock : PUDPsocket; channel : integer );
+cdecl; external{$IFDEF __GPC__}name 'SDLNet_UDP_Unbind'{$ELSE}SDLNetLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDLNet_UDP_Unbind}
+
+{* Get the primary IP address of the remote system associated with the
+ socket and channel. If the channel is -1, then the primary IP port
+ of the UDP socket is returned -- this is only meaningful for sockets
+ opened with a specific port.
+ If the channel is not bound and not -1, this function returns NULL.
+ *}
+function SDLNet_UDP_GetPeerAddress( sock : PUDPsocket; channel : integer ) : PIPAddress;
+cdecl; external{$IFDEF __GPC__}name 'SDLNet_UDP_GetPeerAddress'{$ELSE}SDLNetLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDLNet_UDP_GetPeerAddress}
+
+{* Send a vector of packets to the the channels specified within the packet.
+ If the channel specified in the packet is -1, the packet will be sent to
+ the address in the 'src' member of the packet.
+ Each packet will be updated with the status of the packet after it has
+ been sent, -1 if the packet send failed.
+ This function returns the number of packets sent.
+*}
+function SDLNet_UDP_SendV( sock : PUDPsocket; packets : PPUDPpacket; npackets : integer ) : integer;
+cdecl; external{$IFDEF __GPC__}name 'SDLNet_UDP_SendV'{$ELSE}SDLNetLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDLNet_UDP_SendV}
+
+{* Send a single packet to the specified channel.
+ If the channel specified in the packet is -1, the packet will be sent to
+ the address in the 'src' member of the packet.
+ The packet will be updated with the status of the packet after it has
+ been sent.
+ This function returns 1 if the packet was sent, or 0 on error.
+*}
+function SDLNet_UDP_Send( sock : PUDPsocket; channel : integer; packet : PUDPpacket ) : integer;
+cdecl; external{$IFDEF __GPC__}name 'SDLNet_UDP_Send'{$ELSE}SDLNetLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDLNet_UDP_Send}
+
+{* Receive a vector of pending packets from the UDP socket.
+ The returned packets contain the source address and the channel they arrived
+ on. If they did not arrive on a bound channel, the the channel will be set
+ to -1.
+ The channels are checked in highest to lowest order, so if an address is
+ bound to multiple channels, the highest channel with the source address
+ bound will be returned.
+ This function returns the number of packets read from the network, or -1
+ on error. This function does not block, so can return 0 packets pending.
+*}
+function SDLNet_UDP_RecvV( sock : PUDPsocket; packets : PPUDPpacket ) : integer;
+cdecl; external{$IFDEF __GPC__}name 'SDLNet_UDP_RecvV'{$ELSE}SDLNetLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDLNet_UDP_RecvV}
+
+{* Receive a single packet from the UDP socket.
+ The returned packet contains the source address and the channel it arrived
+ on. If it did not arrive on a bound channel, the the channel will be set
+ to -1.
+ The channels are checked in highest to lowest order, so if an address is
+ bound to multiple channels, the highest channel with the source address
+ bound will be returned.
+ This function returns the number of packets read from the network, or -1
+ on error. This function does not block, so can return 0 packets pending.
+*}
+function SDLNet_UDP_Recv( sock : PUDPsocket; packet : PUDPpacket ) : integer;
+cdecl; external{$IFDEF __GPC__}name 'SDLNet_UDP_Recv'{$ELSE}SDLNetLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDLNet_UDP_Recv}
+
+{* Close a UDP network socket *}
+procedure SDLNet_UDP_Close( sock : PUDPsocket );
+cdecl; external{$IFDEF __GPC__}name 'SDLNet_UDP_Close'{$ELSE}SDLNetLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDLNet_UDP_Close}
+
+ {***********************************************************************}
+ {* Hooks for checking sockets for available data *}
+ {***********************************************************************}
+
+{* Allocate a socket set for use with SDLNet_CheckSockets()
+ This returns a socket set for up to 'maxsockets' sockets, or NULL if
+ the function ran out of memory.
+ *}
+function SDLNet_AllocSocketSet( maxsockets : integer ) : PSDLNet_SocketSet;
+cdecl; external{$IFDEF __GPC__}name 'SDLNet_AllocSocketSet'{$ELSE}SDLNetLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDLNet_AllocSocketSet}
+
+{* Add a socket to a set of sockets to be checked for available data *}
+function SDLNet_AddSocket( set_ : PSDLNet_SocketSet; sock : PSDLNet_GenericSocket ) : integer;
+cdecl; external{$IFDEF __GPC__}name 'SDLNet_AddSocket'{$ELSE}SDLNetLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDLNet_AddSocket}
+
+function SDLNet_TCP_AddSocket( set_ : PSDLNet_SocketSet; sock : PTCPSocket ) : integer;
+
+function SDLNet_UDP_AddSocket( set_ : PSDLNet_SocketSet; sock : PUDPSocket ) : integer;
+
+
+{* Remove a socket from a set of sockets to be checked for available data *}
+function SDLNet_DelSocket( set_ : PSDLNet_SocketSet; sock : PSDLNet_GenericSocket ) : integer;
+cdecl; external{$IFDEF __GPC__}name 'SDLNet_DelSocket'{$ELSE}SDLNetLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDLNet_DelSocket}
+
+function SDLNet_TCP_DelSocket( set_ : PSDLNet_SocketSet; sock : PTCPSocket ) : integer; // SDLNet_DelSocket(set, (SDLNet_GenericSocket)sock)
+
+function SDLNet_UDP_DelSocket( set_ : PSDLNet_SocketSet; sock : PUDPSocket ) : integer; //SDLNet_DelSocket(set, (SDLNet_GenericSocket)sock)
+
+{* This function checks to see if data is available for reading on the
+ given set of sockets. If 'timeout' is 0, it performs a quick poll,
+ otherwise the function returns when either data is available for
+ reading, or the timeout in milliseconds has elapsed, which ever occurs
+ first. This function returns the number of sockets ready for reading,
+ or -1 if there was an error with the select() system call.
+*}
+function SDLNet_CheckSockets( set_ : PSDLNet_SocketSet; timeout : Sint32 ) : integer;
+cdecl; external{$IFDEF __GPC__}name 'SDLNet_CheckSockets'{$ELSE}SDLNetLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDLNet_CheckSockets}
+
+{* After calling SDLNet_CheckSockets(), you can use this function on a
+ socket that was in the socket set, to find out if data is available
+ for reading.
+*}
+function SDLNet_SocketReady( sock : PSDLNet_GenericSocket ) : boolean;
+
+{* Free a set of sockets allocated by SDL_NetAllocSocketSet() *}
+procedure SDLNet_FreeSocketSet( set_ : PSDLNet_SocketSet );
+cdecl; external{$IFDEF __GPC__}name 'SDLNet_FreeSocketSet'{$ELSE}SDLNetLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDLNet_FreeSocketSet}
+
+{***********************************************************************}
+{* Platform-independent data conversion functions *}
+{***********************************************************************}
+
+{* Write a 16/32 bit value to network packet buffer *}
+procedure SDLNet_Write16( value : Uint16; area : Pointer );
+cdecl; external{$IFDEF __GPC__}name 'SDLNet_Write16'{$ELSE}SDLNetLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDLNet_Write16}
+
+procedure SDLNet_Write32( value : Uint32; area : Pointer );
+cdecl; external{$IFDEF __GPC__}name 'SDLNet_Write32'{$ELSE}SDLNetLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDLNet_Write32}
+
+{* Read a 16/32 bit value from network packet buffer *}
+function SDLNet_Read16( area : Pointer ) : Uint16;
+cdecl; external{$IFDEF __GPC__}name 'SDLNet_Read16'{$ELSE}SDLNetLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDLNet_Read16}
+
+function SDLNet_Read32( area : Pointer ) : Uint32;
+cdecl; external{$IFDEF __GPC__}name 'SDLNet_Read32'{$ELSE}SDLNetLibName{$ENDIF __GPC__};
+{$EXTERNALSYM SDLNet_Read32}
+
+{***********************************************************************}
+{* Error reporting functions *}
+{***********************************************************************}
+
+{* We'll use SDL's functions for error reporting *}
+procedure SDLNet_SetError( fmt : PChar );
+function SDLNet_GetError : PChar;
+
+(* I'm eventually going to try to disentangle SDL_net from SDL, thus making
+ SDL_net an independent X-platform networking toolkit. Not today though....
+
+proceudre SDLNet_SetError(const char *fmt, ...);
+cdecl; external {$IFDEF __GPC__}name 'SDLNet_SetError'{$ELSE} SDLNetLibName {$ENDIF __GPC__};
+{$EXTERNALSYM SDLNet_SetError}
+
+function SDLNet_GetError : PChar;
+cdecl; external {$IFDEF __GPC__}name 'SDLNet_GetError'{$ELSE} SDLNetLibName {$ENDIF __GPC__};
+{$EXTERNALSYM SDLNet_GetError}
+*)
+
+implementation
+
+{$IFDEF __GPC__}
+{$L 'sdl_net'} { link sdl_net.dll.a or libsdl_net.so or libsdl_net.a }
+{$ENDIF}
+
+procedure SDL_NET_VERSION( var X : TSDL_version );
+begin
+ X.major := SDL_NET_MAJOR_VERSION;
+ X.minor := SDL_NET_MINOR_VERSION;
+ X.patch := SDL_NET_PATCHLEVEL;
+end;
+
+function SDLNet_TCP_AddSocket( set_ : PSDLNet_SocketSet; sock : PTCPSocket ) : integer;
+begin
+ result := SDLNet_AddSocket( set_, PSDLNet_GenericSocket( sock ) );
+end;
+
+function SDLNet_UDP_AddSocket( set_ : PSDLNet_SocketSet; sock : PUDPSocket ) : integer;
+begin
+ result := SDLNet_AddSocket( set_, PSDLNet_GenericSocket( sock ) );
+end;
+
+function SDLNet_TCP_DelSocket( set_ : PSDLNet_SocketSet; sock : PTCPSocket ) : integer;
+begin
+ result := SDLNet_DelSocket( set_, PSDLNet_GenericSocket( sock ) );
+end;
+
+function SDLNet_UDP_DelSocket( set_ : PSDLNet_SocketSet; sock : PUDPSocket ) : integer;
+begin
+ result := SDLNet_DelSocket( set_, PSDLNet_GenericSocket( sock ) );
+end;
+
+{* After calling SDLNet_CheckSockets(), you can use this function on a
+ socket that was in the socket set, to find out if data is available
+ for reading.
+*}
+
+function SDLNet_SocketReady( sock : PSDLNet_GenericSocket ) : boolean;
+begin
+ result := ( ( sock <> nil ) and ( sock^.ready = 1 ) );
+end;
+
+procedure SDLNet_SetError( fmt : PChar );
+begin
+ SDL_SetError( fmt );
+end;
+
+function SDLNet_GetError : PChar;
+begin
+ result := SDL_GetError;
+end;
+
+end.
+
diff --git a/packages/sdl/src/sdl_ttf.pas b/packages/sdl/src/sdl_ttf.pas
new file mode 100644
index 0000000000..22424944c9
--- /dev/null
+++ b/packages/sdl/src/sdl_ttf.pas
@@ -0,0 +1,501 @@
+unit sdl_ttf;
+{
+ $Id: sdl_ttf.pas,v 1.18 2007/06/01 11:16:33 savage Exp $
+
+}
+{******************************************************************************}
+{ }
+{ JEDI-SDL : Pascal units for SDL - Simple DirectMedia Layer }
+{ Conversion of the Simple DirectMedia Layer Headers }
+{ }
+{ Portions created by Sam Lantinga <slouken@devolution.com> are }
+{ Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga }
+{ 5635-34 Springhouse Dr. }
+{ Pleasanton, CA 94588 (USA) }
+{ }
+{ All Rights Reserved. }
+{ }
+{ The original files are : SDL_ttf.h }
+{ }
+{ The initial developer of this Pascal code was : }
+{ Dominqiue Louis <Dominique@SavageSoftware.com.au> }
+{ }
+{ Portions created by Dominqiue Louis are }
+{ Copyright (C) 2000 - 2001 Dominqiue Louis. }
+{ }
+{ }
+{ Contributor(s) }
+{ -------------- }
+{ Tom Jones <tigertomjones@gmx.de> His Project inspired this conversion }
+{ }
+{ Obtained through: }
+{ Joint Endeavour of Delphi Innovators ( Project JEDI ) }
+{ }
+{ You may retrieve the latest version of this file at the Project }
+{ JEDI home page, located at http://delphi-jedi.org }
+{ }
+{ The contents of this file are used with permission, subject to }
+{ the Mozilla Public License Version 1.1 (the "License"); you may }
+{ not use this file except in compliance with the License. You may }
+{ obtain a copy of the License at }
+{ http://www.mozilla.org/MPL/MPL-1.1.html }
+{ }
+{ Software distributed under the License is distributed on an }
+{ "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or }
+{ implied. See the License for the specific language governing }
+{ rights and limitations under the License. }
+{ }
+{ Description }
+{ ----------- }
+{ }
+{ }
+{ }
+{ }
+{ }
+{ }
+{ }
+{ Requires }
+{ -------- }
+{ The SDL Runtime libraris on Win32 : SDL.dll on Linux : libSDL.so }
+{ They are available from... }
+{ http://www.libsdl.org . }
+{ }
+{ Programming Notes }
+{ ----------------- }
+{ }
+{ }
+{ }
+{ }
+{ Revision History }
+{ ---------------- }
+{ December 08 2002 - DL : Fixed definition of TTF_RenderUnicode_Solid }
+{ }
+{ April 03 2003 - DL : Added jedi-sdl.inc include file to support more }
+{ Pascal compilers. Initial support is now included }
+{ for GnuPascal, VirtualPascal, TMT and obviously }
+{ continue support for Delphi Kylix and FreePascal. }
+{ }
+{ April 24 2003 - DL : under instruction from Alexey Barkovoy, I have added}
+{ better TMT Pascal support and under instruction }
+{ from Prof. Abimbola Olowofoyeku (The African Chief),}
+{ I have added better Gnu Pascal support }
+{ }
+{ April 30 2003 - DL : under instruction from David Mears AKA }
+{ Jason Siletto, I have added FPC Linux support. }
+{ This was compiled with fpc 1.1, so remember to set }
+{ include file path. ie. -Fi/usr/share/fpcsrc/rtl/* }
+{ }
+{
+ $Log: sdl_ttf.pas,v $
+ Revision 1.18 2007/06/01 11:16:33 savage
+ Added IFDEF UNIX for Workaround.
+
+ Revision 1.17 2007/06/01 08:38:21 savage
+ Added TTF_RenderText_Solid workaround as suggested by Michalis Kamburelis
+
+ Revision 1.16 2007/05/29 21:32:14 savage
+ Changes as suggested by Almindor for 64bit compatibility.
+
+ Revision 1.15 2007/05/20 20:32:45 savage
+ Initial Changes to Handle 64 Bits
+
+ Revision 1.14 2006/12/02 00:19:01 savage
+ Updated to latest version
+
+ Revision 1.13 2005/04/10 11:48:33 savage
+ Changes as suggested by Michalis, thanks.
+
+ Revision 1.12 2005/01/05 01:47:14 savage
+ Changed LibName to reflect what MacOS X should have. ie libSDL*-1.2.0.dylib respectively.
+
+ Revision 1.11 2005/01/04 23:14:57 savage
+ Changed LibName to reflect what most Linux distros will have. ie libSDL*-1.2.so.0 respectively.
+
+ Revision 1.10 2005/01/02 19:07:32 savage
+ Slight bug fix to use LongInt instead of Long ( Thanks Michalis Kamburelis )
+
+ Revision 1.9 2005/01/01 02:15:20 savage
+ Updated to v2.0.7
+
+ Revision 1.8 2004/10/07 21:02:32 savage
+ Fix for FPC
+
+ Revision 1.7 2004/09/30 22:39:50 savage
+ Added a true type font class which contains a wrap text function.
+ Changed the sdl_ttf.pas header to reflect the future of jedi-sdl.
+
+ Revision 1.6 2004/08/14 22:54:30 savage
+ Updated so that Library name defines are correctly defined for MacOS X.
+
+ Revision 1.5 2004/05/10 14:10:04 savage
+ Initial MacOS X support. Fixed defines for MACOS ( Classic ) and DARWIN ( MacOS X ).
+
+ Revision 1.4 2004/04/13 09:32:08 savage
+ Changed Shared object names back to just the .so extension to avoid conflicts on various Linux/Unix distros. Therefore developers will need to create Symbolic links to the actual Share Objects if necessary.
+
+ Revision 1.3 2004/04/01 20:53:24 savage
+ Changed Linux Shared Object names so they reflect the Symbolic Links that are created when installing the RPMs from the SDL site.
+
+ Revision 1.2 2004/03/30 20:23:28 savage
+ Tidied up use of UNIX compiler directive.
+
+ Revision 1.1 2004/02/16 22:16:40 savage
+ v1.0 changes
+
+
+}
+{******************************************************************************}
+
+{$I jedi-sdl.inc}
+
+{
+ Define this to workaround a known bug in some freetype versions.
+ The error manifests as TTF_RenderGlyph_Solid returning nil (error)
+ and error message (in SDL_Error) is
+ "Failed loading DPMSDisable: /usr/lib/libX11.so.6: undefined symbol: DPMSDisable"
+ See [http://lists.libsdl.org/pipermail/sdl-libsdl.org/2007-March/060459.html]
+}
+{$IFDEF UNIX}
+{$DEFINE Workaround_TTF_RenderText_Solid}
+{$ENDIF}
+
+
+interface
+
+uses
+{$IFDEF __GPC__}
+ gpc,
+{$ENDIF}
+
+{$IFDEF WINDOWS}
+ {$IFNDEF __GPC__}
+ Windows,
+ {$ENDIF}
+{$ENDIF}
+ sdl;
+
+const
+{$IFDEF WINDOWS}
+ SDLttfLibName = 'SDL_ttf.dll';
+{$ENDIF}
+
+{$IFDEF UNIX}
+{$IFDEF DARWIN}
+ SDLttfLibName = 'libSDL_ttf-2.0.0.dylib';
+{$ELSE}
+ {$IFDEF FPC}
+ SDLttfLibName = 'libSDL_ttf.so';
+ {$ELSE}
+ SDLttfLibName = 'libSDL_ttf-2.0.so.0';
+ {$ENDIF}
+{$ENDIF}
+{$ENDIF}
+
+{$IFDEF MACOS}
+ SDLttfLibName = 'SDL_ttf';
+{$ENDIF}
+
+ {* Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL *}
+ SDL_TTF_MAJOR_VERSION = 2;
+{$EXTERNALSYM SDL_TTF_MAJOR_VERSION}
+ SDL_TTF_MINOR_VERSION = 0;
+{$EXTERNALSYM SDL_TTF_MINOR_VERSION}
+ SDL_TTF_PATCHLEVEL = 8;
+{$EXTERNALSYM SDL_TTF_PATCHLEVEL}
+
+ // Backwards compatibility
+ TTF_MAJOR_VERSION = SDL_TTF_MAJOR_VERSION;
+ TTF_MINOR_VERSION = SDL_TTF_MINOR_VERSION;
+ TTF_PATCHLEVEL = SDL_TTF_PATCHLEVEL;
+
+{*
+ Set and retrieve the font style
+ This font style is implemented by modifying the font glyphs, and
+ doesn't reflect any inherent properties of the truetype font file.
+*}
+ TTF_STYLE_NORMAL = $00;
+ TTF_STYLE_BOLD = $01;
+ TTF_STYLE_ITALIC = $02;
+ TTF_STYLE_UNDERLINE = $04;
+
+// ZERO WIDTH NO-BREAKSPACE (Unicode byte order mark)
+ UNICODE_BOM_NATIVE = $FEFF;
+ UNICODE_BOM_SWAPPED = $FFFE;
+
+type
+ PTTF_Font = ^TTTF_font;
+ TTTF_Font = record
+ end;
+
+{ This macro can be used to fill a version structure with the compile-time
+ version of the SDL_ttf library. }
+procedure SDL_TTF_VERSION( var X : TSDL_version );
+{$EXTERNALSYM SDL_TTF_VERSION}
+
+{ This function gets the version of the dynamically linked SDL_ttf library.
+ It should NOT be used to fill a version structure, instead you should use the
+ SDL_TTF_VERSION() macro. }
+function TTF_Linked_Version : PSDL_version;
+cdecl; external {$IFDEF __GPC__}name 'TTF_Linked_Version'{$ELSE} SDLttfLibName{$ENDIF __GPC__};
+{$EXTERNALSYM TTF_Linked_Version}
+
+{ This function tells the library whether UNICODE text is generally
+ byteswapped. A UNICODE BOM character in a string will override
+ this setting for the remainder of that string.
+}
+procedure TTF_ByteSwappedUNICODE( swapped : integer );
+cdecl; external {$IFDEF __GPC__}name 'TTF_ByteSwappedUNICODE'{$ELSE} SDLttfLibName{$ENDIF __GPC__};
+{$EXTERNALSYM TTF_ByteSwappedUNICODE}
+
+//returns 0 on succes, -1 if error occurs
+function TTF_Init : integer;
+cdecl; external {$IFDEF __GPC__}name 'TTF_Init'{$ELSE} SDLttfLibName{$ENDIF __GPC__};
+{$EXTERNALSYM TTF_Init}
+
+{
+ Open a font file and create a font of the specified point size.
+ Some .fon fonts will have several sizes embedded in the file, so the
+ point size becomes the index of choosing which size. If the value
+ is too high, the last indexed size will be the default.
+}
+function TTF_OpenFont( const filename : Pchar; ptsize : integer ) : PTTF_Font;
+cdecl; external {$IFDEF __GPC__}name 'TTF_OpenFont'{$ELSE} SDLttfLibName{$ENDIF __GPC__};
+{$EXTERNALSYM TTF_OpenFont}
+
+function TTF_OpenFontIndex( const filename : Pchar; ptsize : integer; index : Longint ): PTTF_Font;
+cdecl; external {$IFDEF __GPC__}name 'TTF_OpenFontIndex'{$ELSE} SDLttfLibName{$ENDIF __GPC__};
+{$EXTERNALSYM TTF_OpenFontIndex}
+
+function TTF_OpenFontRW( src : PSDL_RWops; freesrc : integer; ptsize : integer ): PTTF_Font;
+cdecl; external {$IFDEF __GPC__}name 'TTF_OpenFontRW'{$ELSE} SDLttfLibName{$ENDIF __GPC__};
+{$EXTERNALSYM TTF_OpenFontRW}
+
+function TTF_OpenFontIndexRW( src : PSDL_RWops; freesrc : integer; ptsize : integer; index : Longint ): PTTF_Font;
+cdecl; external {$IFDEF __GPC__}name 'TTF_OpenFontIndexRW'{$ELSE} SDLttfLibName{$ENDIF __GPC__};
+{$EXTERNALSYM TTF_OpenFontIndexRW}
+
+function TTF_GetFontStyle( font : PTTF_Font) : integer;
+cdecl; external {$IFDEF __GPC__}name 'TTF_GetFontStyle'{$ELSE} SDLttfLibName{$ENDIF __GPC__};
+{$EXTERNALSYM TTF_GetFontStyle}
+
+procedure TTF_SetFontStyle( font : PTTF_Font; style : integer );
+cdecl; external {$IFDEF __GPC__}name 'TTF_SetFontStyle'{$ELSE} SDLttfLibName{$ENDIF __GPC__};
+{$EXTERNALSYM TTF_SetFontStyle}
+
+{ Get the total height of the font - usually equal to point size }
+function TTF_FontHeight( font : PTTF_Font ) : Integer;
+cdecl; external {$IFDEF __GPC__}name 'TTF_FontHeight'{$ELSE} SDLttfLibName{$ENDIF __GPC__};
+{$EXTERNALSYM TTF_FontHeight}
+
+{ Get the offset from the baseline to the top of the font
+ This is a positive value, relative to the baseline.
+}
+function TTF_FontAscent( font : PTTF_Font ) : Integer;
+cdecl; external {$IFDEF __GPC__}name 'TTF_FontAscent'{$ELSE} SDLttfLibName{$ENDIF __GPC__};
+{$EXTERNALSYM TTF_FontAscent}
+{ Get the offset from the baseline to the bottom of the font
+ This is a negative value, relative to the baseline.
+}
+function TTF_FontDescent( font : PTTF_Font ) : Integer;
+cdecl; external {$IFDEF __GPC__}name 'TTF_FontDescent'{$ELSE} SDLttfLibName{$ENDIF __GPC__};
+{$EXTERNALSYM TTF_FontDescent}
+
+{ Get the recommended spacing between lines of text for this font }
+function TTF_FontLineSkip( font : PTTF_Font ): Integer;
+cdecl; external {$IFDEF __GPC__}name 'TTF_FontLineSkip'{$ELSE} SDLttfLibName{$ENDIF __GPC__};
+{$EXTERNALSYM TTF_FontLineSkip}
+
+{ Get the number of faces of the font }
+function TTF_FontFaces( font : PTTF_Font ) : Longint;
+cdecl; external {$IFDEF __GPC__}name 'TTF_FontFaces'{$ELSE} SDLttfLibName{$ENDIF __GPC__};
+{$EXTERNALSYM TTF_FontFaces}
+
+{ Get the font face attributes, if any }
+function TTF_FontFaceIsFixedWidth( font : PTTF_Font ): Integer;
+cdecl; external {$IFDEF __GPC__}name 'TTF_FontFaceIsFixedWidth'{$ELSE} SDLttfLibName{$ENDIF __GPC__};
+{$EXTERNALSYM TTF_FontFaceIsFixedWidth}
+
+function TTF_FontFaceFamilyName( font : PTTF_Font ): PChar;
+cdecl; external {$IFDEF __GPC__}name 'TTF_FontFaceFamilyName'{$ELSE} SDLttfLibName{$ENDIF __GPC__};
+{$EXTERNALSYM TTF_FontFaceFamilyName}
+
+function TTF_FontFaceStyleName( font : PTTF_Font ): PChar;
+cdecl; external {$IFDEF __GPC__}name 'TTF_FontFaceStyleName'{$ELSE} SDLttfLibName{$ENDIF __GPC__};
+{$EXTERNALSYM TTF_FontFaceStyleName}
+
+{ Get the metrics (dimensions) of a glyph }
+function TTF_GlyphMetrics( font : PTTF_Font; ch : Uint16;
+ var minx : integer; var maxx : integer;
+ var miny : integer; var maxy : integer;
+ var advance : integer ): Integer;
+cdecl; external {$IFDEF __GPC__}name 'TTF_GlyphMetrics'{$ELSE} SDLttfLibName{$ENDIF __GPC__};
+{$EXTERNALSYM TTF_GlyphMetrics}
+
+{ Get the dimensions of a rendered string of text }
+function TTF_SizeText( font : PTTF_Font; const text : PChar; var w : integer; var y : integer ): Integer;
+cdecl; external {$IFDEF __GPC__}name 'TTF_SizeText'{$ELSE} SDLttfLibName{$ENDIF __GPC__};
+{$EXTERNALSYM TTF_SizeText}
+
+function TTF_SizeUTF8( font : PTTF_Font; const text : PChar; var w : integer; var y : integer): Integer;
+cdecl; external {$IFDEF __GPC__}name 'TTF_SizeUTF8'{$ELSE} SDLttfLibName{$ENDIF __GPC__};
+{$EXTERNALSYM TTF_SizeUTF8}
+
+function TTF_SizeUNICODE( font : PTTF_Font; const text : PUint16; var w : integer; var y : integer): Integer;
+cdecl; external {$IFDEF __GPC__}name 'TTF_SizeUNICODE'{$ELSE} SDLttfLibName{$ENDIF __GPC__};
+{$EXTERNALSYM TTF_SizeUNICODE}
+
+{ Create an 8-bit palettized surface and render the given text at
+ fast quality with the given font and color. The 0 pixel is the
+ colorkey, giving a transparent background, and the 1 pixel is set
+ to the text color.
+ This function returns the new surface, or NULL if there was an error.
+}
+function TTF_RenderText_Solid( font : PTTF_Font;
+ const text : PChar; fg : TSDL_Color ): PSDL_Surface;
+{$IFNDEF Workaround_TTF_RenderText_Solid}
+cdecl; external {$IFDEF __GPC__}name 'TTF_RenderText_Solid'{$ELSE} SDLttfLibName{$ENDIF __GPC__};
+{$EXTERNALSYM TTF_RenderText_Solid}
+{$ENDIF}
+
+function TTF_RenderUTF8_Solid( font : PTTF_Font;
+ const text : PChar; fg : TSDL_Color ): PSDL_Surface;
+cdecl; external {$IFDEF __GPC__}name 'TTF_RenderUTF8_Solid'{$ELSE} SDLttfLibName{$ENDIF __GPC__};
+{$EXTERNALSYM TTF_RenderUTF8_Solid}
+
+function TTF_RenderUNICODE_Solid( font : PTTF_Font;
+ const text :PUint16; fg : TSDL_Color ): PSDL_Surface;
+cdecl; external {$IFDEF __GPC__}name 'TTF_RenderUNICODE_Solid'{$ELSE} SDLttfLibName{$ENDIF __GPC__};
+{$EXTERNALSYM TTF_RenderUNICODE_Solid}
+
+{
+Create an 8-bit palettized surface and render the given glyph at
+ fast quality with the given font and color. The 0 pixel is the
+ colorkey, giving a transparent background, and the 1 pixel is set
+ to the text color. The glyph is rendered without any padding or
+ centering in the X direction, and aligned normally in the Y direction.
+ This function returns the new surface, or NULL if there was an error.
+}
+function TTF_RenderGlyph_Solid( font : PTTF_Font;
+ ch : Uint16; fg : TSDL_Color ): PSDL_Surface;
+cdecl; external {$IFDEF __GPC__}name 'TTF_RenderGlyph_Solid'{$ELSE} SDLttfLibName{$ENDIF __GPC__};
+{$EXTERNALSYM TTF_RenderGlyph_Solid}
+
+{ Create an 8-bit palettized surface and render the given text at
+ high quality with the given font and colors. The 0 pixel is background,
+ while other pixels have varying degrees of the foreground color.
+ This function returns the new surface, or NULL if there was an error.
+}
+function TTF_RenderText_Shaded( font : PTTF_Font;
+ const text : PChar; fg : TSDL_Color; bg : TSDL_Color ): PSDL_Surface;
+cdecl; external {$IFDEF __GPC__}name 'TTF_RenderText_Shaded'{$ELSE} SDLttfLibName{$ENDIF __GPC__};
+{$EXTERNALSYM TTF_RenderText_Shaded}
+function TTF_RenderUTF8_Shaded( font : PTTF_Font;
+ const text : PChar; fg : TSDL_Color; bg : TSDL_Color ): PSDL_Surface;
+cdecl; external {$IFDEF __GPC__}name 'TTF_RenderUTF8_Shaded'{$ELSE} SDLttfLibName{$ENDIF __GPC__};
+{$EXTERNALSYM TTF_RenderUTF8_Shaded}
+function TTF_RenderUNICODE_Shaded( font : PTTF_Font;
+ const text : PUint16; fg : TSDL_Color; bg : TSDL_Color ): PSDL_Surface;
+cdecl; external {$IFDEF __GPC__}name 'TTF_RenderUNICODE_Shaded'{$ELSE} SDLttfLibName{$ENDIF __GPC__};
+{$EXTERNALSYM TTF_RenderUNICODE_Shaded}
+
+{ Create an 8-bit palettized surface and render the given glyph at
+ high quality with the given font and colors. The 0 pixel is background,
+ while other pixels have varying degrees of the foreground color.
+ The glyph is rendered without any padding or centering in the X
+ direction, and aligned normally in the Y direction.
+ This function returns the new surface, or NULL if there was an error.
+}
+function TTF_RenderGlyph_Shaded( font : PTTF_Font; ch : Uint16; fg : TSDL_Color;
+ bg : TSDL_Color ): PSDL_Surface;
+cdecl; external {$IFDEF __GPC__}name 'TTF_RenderGlyph_Shaded'{$ELSE} SDLttfLibName{$ENDIF __GPC__};
+{$EXTERNALSYM TTF_RenderGlyph_Shaded}
+
+{ Create a 32-bit ARGB surface and render the given text at high quality,
+ using alpha blending to dither the font with the given color.
+ This function returns the new surface, or NULL if there was an error.
+}
+function TTF_RenderText_Blended( font : PTTF_Font;
+ const text : PChar; fg : TSDL_Color ): PSDL_Surface;
+cdecl; external {$IFDEF __GPC__}name 'TTF_RenderText_Blended'{$ELSE} SDLttfLibName{$ENDIF __GPC__};
+{$EXTERNALSYM TTF_RenderText_Blended}
+function TTF_RenderUTF8_Blended( font : PTTF_Font;
+ const text : PChar; fg : TSDL_Color ): PSDL_Surface;
+cdecl; external {$IFDEF __GPC__}name 'TTF_RenderUTF8_Blended'{$ELSE} SDLttfLibName{$ENDIF __GPC__};
+{$EXTERNALSYM TTF_RenderUTF8_Blended}
+function TTF_RenderUNICODE_Blended( font : PTTF_Font;
+ const text: PUint16; fg : TSDL_Color ): PSDL_Surface;
+cdecl; external {$IFDEF __GPC__}name 'TTF_RenderUNICODE_Blended'{$ELSE} SDLttfLibName{$ENDIF __GPC__};
+{$EXTERNALSYM TTF_RenderUNICODE_Blended}
+
+{ Create a 32-bit ARGB surface and render the given glyph at high quality,
+ using alpha blending to dither the font with the given color.
+ The glyph is rendered without any padding or centering in the X
+ direction, and aligned normally in the Y direction.
+ This function returns the new surface, or NULL if there was an error.
+}
+function TTF_RenderGlyph_Blended( font : PTTF_Font; ch : Uint16; fg : TSDL_Color ): PSDL_Surface;
+cdecl; external {$IFDEF __GPC__}name 'TTF_RenderGlyph_Blended'{$ELSE} SDLttfLibName{$ENDIF __GPC__};
+{$EXTERNALSYM TTF_RenderGlyph_Blended}
+
+{ For compatibility with previous versions, here are the old functions }
+{#define TTF_RenderText(font, text, fg, bg)
+ TTF_RenderText_Shaded(font, text, fg, bg)
+#define TTF_RenderUTF8(font, text, fg, bg)
+ TTF_RenderUTF8_Shaded(font, text, fg, bg)
+#define TTF_RenderUNICODE(font, text, fg, bg)
+ TTF_RenderUNICODE_Shaded(font, text, fg, bg)}
+
+{ Close an opened font file }
+procedure TTF_CloseFont( font : PTTF_Font );
+cdecl; external {$IFDEF __GPC__}name 'TTF_CloseFont'{$ELSE} SDLttfLibName{$ENDIF __GPC__};
+{$EXTERNALSYM TTF_CloseFont}
+
+//De-initialize TTF engine
+procedure TTF_Quit;
+cdecl; external {$IFDEF __GPC__}name 'TTF_Quit'{$ELSE} SDLttfLibName{$ENDIF __GPC__};
+{$EXTERNALSYM TTF_Quit}
+
+// Check if the TTF engine is initialized
+function TTF_WasInit : integer;
+cdecl; external {$IFDEF __GPC__}name 'TTF_WasInit'{$ELSE} SDLttfLibName{$ENDIF __GPC__};
+{$EXTERNALSYM TTF_WasInit}
+
+// We'll use SDL for reporting errors
+procedure TTF_SetError( fmt : PChar );
+
+function TTF_GetError : PChar;
+
+implementation
+
+{$IFDEF __GPC__}
+ {$L 'sdl_ttf'} { link sdl_ttf.dll.a or libsdl_ttf.so or libsdl_ttf.a }
+{$ENDIF}
+
+procedure SDL_TTF_VERSION( var X : TSDL_version );
+begin
+ X.major := SDL_TTF_MAJOR_VERSION;
+ X.minor := SDL_TTF_MINOR_VERSION;
+ X.patch := SDL_TTF_PATCHLEVEL;
+end;
+
+procedure TTF_SetError( fmt : PChar );
+begin
+ SDL_SetError( fmt );
+end;
+
+function TTF_GetError : PChar;
+begin
+ result := SDL_GetError;
+end;
+
+{$IFDEF Workaround_TTF_RenderText_Solid}
+function TTF_RenderText_Solid( font : PTTF_Font;
+ const text : PChar; fg : TSDL_Color ): PSDL_Surface;
+const
+ Black: TSDL_Color = (r: 0; g: 0; b: 0; unused: 0);
+begin
+ Result := TTF_RenderText_Shaded(font, text, fg, Black);
+end;
+{$ENDIF Workaround_TTF_RenderText_Solid}
+
+end.
diff --git a/packages/sdl/src/sdlutils.pas b/packages/sdl/src/sdlutils.pas
new file mode 100644
index 0000000000..01f67685b4
--- /dev/null
+++ b/packages/sdl/src/sdlutils.pas
@@ -0,0 +1,4363 @@
+unit sdlutils;
+{
+ $Id: sdlutils.pas,v 1.5 2006/11/19 18:56:44 savage Exp $
+
+}
+{******************************************************************************}
+{ }
+{ Borland Delphi SDL - Simple DirectMedia Layer }
+{ SDL Utility functions }
+{ }
+{ }
+{ The initial developer of this Pascal code was : }
+{ Tom Jones <tigertomjones@gmx.de> }
+{ }
+{ Portions created by Tom Jones are }
+{ Copyright (C) 2000 - 2001 Tom Jones. }
+{ }
+{ }
+{ Contributor(s) }
+{ -------------- }
+{ Dominique Louis <Dominique@SavageSoftware.com.au> }
+{ Róbert Kisnémeth <mikrobi@freemail.hu> }
+{ }
+{ Obtained through: }
+{ Joint Endeavour of Delphi Innovators ( Project JEDI ) }
+{ }
+{ You may retrieve the latest version of this file at the Project }
+{ JEDI home page, located at http://delphi-jedi.org }
+{ }
+{ The contents of this file are used with permission, subject to }
+{ the Mozilla Public License Version 1.1 (the "License"); you may }
+{ not use this file except in compliance with the License. You may }
+{ obtain a copy of the License at }
+{ http://www.mozilla.org/MPL/MPL-1.1.html }
+{ }
+{ Software distributed under the License is distributed on an }
+{ "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or }
+{ implied. See the License for the specific language governing }
+{ rights and limitations under the License. }
+{ }
+{ Description }
+{ ----------- }
+{ Helper functions... }
+{ }
+{ }
+{ Requires }
+{ -------- }
+{ SDL.dll on Windows platforms }
+{ libSDL-1.1.so.0 on Linux platform }
+{ }
+{ Programming Notes }
+{ ----------------- }
+{ }
+{ }
+{ }
+{ }
+{ Revision History }
+{ ---------------- }
+{ 2000 - TJ : Initial creation }
+{ }
+{ July 13 2001 - DL : Added PutPixel and GetPixel routines. }
+{ }
+{ Sept 14 2001 - RK : Added flipping routines. }
+{ }
+{ Sept 19 2001 - RK : Added PutPixel & line drawing & blitting with ADD }
+{ effect. Fixed a bug in SDL_PutPixel & SDL_GetPixel }
+{ Added PSDLRect() }
+{ Sept 22 2001 - DL : Removed need for Windows.pas by defining types here}
+{ Also removed by poor attempt or a dialog box }
+{ }
+{ Sept 25 2001 - RK : Added PixelTest, NewPutPixel, SubPixel, SubLine, }
+{ SubSurface, MonoSurface & TexturedSurface }
+{ }
+{ Sept 26 2001 - DL : Made change so that it refers to native Pascal }
+{ types rather that Windows types. This makes it more}
+{ portable to Linix. }
+{ }
+{ Sept 27 2001 - RK : SDLUtils now can be compiled with FreePascal }
+{ }
+{ Oct 27 2001 - JF : Added ScrollY function }
+{ }
+{ Jan 21 2002 - RK : Added SDL_ZoomSurface and SDL_WarpSurface }
+{ }
+{ Mar 28 2002 - JF : Added SDL_RotateSurface }
+{ }
+{ May 13 2002 - RK : Improved SDL_FillRectAdd & SDL_FillRectSub }
+{ }
+{ May 27 2002 - YS : GradientFillRect function }
+{ }
+{ May 30 2002 - RK : Added SDL_2xBlit, SDL_Scanline2xBlit }
+{ & SDL_50Scanline2xBlit }
+{ }
+{ June 12 2002 - RK : Added SDL_PixelTestSurfaceVsRect }
+{ }
+{ June 12 2002 - JF : Updated SDL_PixelTestSurfaceVsRect }
+{ }
+{ November 9 2002 - JF : Added Jason's boolean Surface functions }
+{ }
+{ December 10 2002 - DE : Added Dean's SDL_ClipLine function }
+{ }
+{ April 26 2003 - SS : Incorporated JF's changes to SDL_ClipLine }
+{ Fixed SDL_ClipLine bug for non-zero cliprect x, y }
+{ Added overloaded SDL_DrawLine for dashed lines }
+{ }
+{******************************************************************************}
+{
+ $Log: sdlutils.pas,v $
+ Revision 1.5 2006/11/19 18:56:44 savage
+ Removed Hints and Warnings.
+
+ Revision 1.4 2004/06/02 19:38:53 savage
+ Changes to SDL_GradientFillRect as suggested by
+ Ángel Eduardo García Hernández. Many thanks.
+
+ Revision 1.3 2004/05/29 23:11:54 savage
+ Changes to SDL_ScaleSurfaceRect as suggested by
+ Ángel Eduardo García Hernández to fix a colour issue with the function. Many thanks.
+
+ Revision 1.2 2004/02/14 00:23:39 savage
+ As UNIX is defined in jedi-sdl.inc this will be used to check linux compatability as well. Units have been changed to reflect this change.
+
+ Revision 1.1 2004/02/05 00:08:20 savage
+ Module 1.0 release
+
+
+}
+
+interface
+
+{$I jedi-sdl.inc}
+
+uses
+{$IFDEF UNIX}
+ Types,
+{$IFNDEF DARWIN}
+ Xlib,
+{$ENDIF}
+{$ENDIF}
+ SysUtils,
+ sdl;
+
+type
+ TGradientStyle = ( gsHorizontal, gsVertical );
+
+// Pixel procedures
+function SDL_PixelTest( SrcSurface1 : PSDL_Surface; SrcRect1 : PSDL_Rect; SrcSurface2 :
+ PSDL_Surface; SrcRect2 : PSDL_Rect; Left1, Top1, Left2, Top2 : integer ) : Boolean;
+
+function SDL_GetPixel( SrcSurface : PSDL_Surface; x : integer; y : integer ) : Uint32;
+
+procedure SDL_PutPixel( DstSurface : PSDL_Surface; x : integer; y : integer; pixel :
+ Uint32 );
+
+procedure SDL_AddPixel( DstSurface : PSDL_Surface; x : cardinal; y : cardinal; Color :
+ cardinal );
+
+procedure SDL_SubPixel( DstSurface : PSDL_Surface; x : cardinal; y : cardinal; Color :
+ cardinal );
+
+// Line procedures
+procedure SDL_DrawLine( DstSurface : PSDL_Surface; x1, y1, x2, y2 : integer; Color :
+ cardinal ); overload;
+
+procedure SDL_DrawLine( DstSurface : PSDL_Surface; x1, y1, x2, y2 : integer; Color :
+ cardinal; DashLength, DashSpace : byte ); overload;
+
+procedure SDL_AddLine( DstSurface : PSDL_Surface; x1, y1, x2, y2 : integer; Color :
+ cardinal );
+
+procedure SDL_SubLine( DstSurface : PSDL_Surface; x1, y1, x2, y2 : integer; Color :
+ cardinal );
+
+// Surface procedures
+procedure SDL_AddSurface( SrcSurface : PSDL_Surface; SrcRect : PSDL_Rect;
+ DestSurface : PSDL_Surface; DestRect : PSDL_Rect );
+
+procedure SDL_SubSurface( SrcSurface : PSDL_Surface; SrcRect : PSDL_Rect;
+ DestSurface : PSDL_Surface; DestRect : PSDL_Rect );
+
+procedure SDL_MonoSurface( SrcSurface : PSDL_Surface; SrcRect : PSDL_Rect;
+ DestSurface : PSDL_Surface; DestRect : PSDL_Rect; Color : cardinal );
+
+procedure SDL_TexturedSurface( SrcSurface : PSDL_Surface; SrcRect : PSDL_Rect;
+ DestSurface : PSDL_Surface; DestRect : PSDL_Rect; Texture : PSDL_Surface;
+ TextureRect : PSDL_Rect );
+
+procedure SDL_ZoomSurface( SrcSurface : PSDL_Surface; SrcRect : PSDL_Rect; DstSurface : PSDL_Surface; DstRect : PSDL_Rect );
+
+procedure SDL_WarpSurface( SrcSurface : PSDL_Surface; SrcRect : PSDL_Rect; DstSurface : PSDL_Surface; UL, UR, LR, LL : PPoint );
+
+// Flip procedures
+procedure SDL_FlipRectH( DstSurface : PSDL_Surface; Rect : PSDL_Rect );
+
+procedure SDL_FlipRectV( DstSurface : PSDL_Surface; Rect : PSDL_Rect );
+
+function PSDLRect( aLeft, aTop, aWidth, aHeight : integer ) : PSDL_Rect;
+
+function SDLRect( aLeft, aTop, aWidth, aHeight : integer ) : TSDL_Rect; overload;
+
+function SDLRect( aRect : TRect ) : TSDL_Rect; overload;
+
+function SDL_ScaleSurfaceRect( SrcSurface : PSDL_Surface; SrcX1, SrcY1, SrcW, SrcH,
+ Width, Height : integer ) : PSDL_Surface;
+
+procedure SDL_ScrollY( DstSurface : PSDL_Surface; DifY : integer );
+
+procedure SDL_ScrollX( DstSurface : PSDL_Surface; DifX : integer );
+
+procedure SDL_RotateDeg( DstSurface, SrcSurface : PSDL_Surface; SrcRect :
+ PSDL_Rect; DestX, DestY, OffsetX, OffsetY : Integer; Angle : Integer );
+
+procedure SDL_RotateRad( DstSurface, SrcSurface : PSDL_Surface; SrcRect :
+ PSDL_Rect; DestX, DestY, OffsetX, OffsetY : Integer; Angle : Single );
+
+function ValidateSurfaceRect( DstSurface : PSDL_Surface; dstrect : PSDL_Rect ) : TSDL_Rect;
+
+// Fill Rect routine
+procedure SDL_FillRectAdd( DstSurface : PSDL_Surface; dstrect : PSDL_Rect; color : UInt32 );
+
+procedure SDL_FillRectSub( DstSurface : PSDL_Surface; dstrect : PSDL_Rect; color : UInt32 );
+
+procedure SDL_GradientFillRect( DstSurface : PSDL_Surface; const Rect : PSDL_Rect; const StartColor, EndColor : TSDL_Color; const Style : TGradientStyle );
+
+// NOTE for All SDL_2xblit... function : the dest surface must be 2x of the source surface!
+procedure SDL_2xBlit( Src, Dest : PSDL_Surface );
+
+procedure SDL_Scanline2xBlit( Src, Dest : PSDL_Surface );
+
+procedure SDL_50Scanline2xBlit( Src, Dest : PSDL_Surface );
+
+//
+function SDL_PixelTestSurfaceVsRect( SrcSurface1 : PSDL_Surface; SrcRect1 :
+ PSDL_Rect; SrcRect2 : PSDL_Rect; Left1, Top1, Left2, Top2 : integer ) :
+ boolean;
+
+// Jason's boolean Surface functions
+procedure SDL_ORSurface( SrcSurface : PSDL_Surface; SrcRect : PSDL_Rect;
+ DestSurface : PSDL_Surface; DestRect : PSDL_Rect );
+
+procedure SDL_ANDSurface( SrcSurface : PSDL_Surface; SrcRect : PSDL_Rect;
+ DestSurface : PSDL_Surface; DestRect : PSDL_Rect );
+
+
+procedure SDL_GTSurface( SrcSurface : PSDL_Surface; SrcRect : PSDL_Rect;
+ DestSurface : PSDL_Surface; DestRect : PSDL_Rect );
+
+procedure SDL_LTSurface( SrcSurface : PSDL_Surface; SrcRect : PSDL_Rect;
+ DestSurface : PSDL_Surface; DestRect : PSDL_Rect );
+
+function SDL_ClipLine( var x1, y1, x2, y2 : Integer; ClipRect : PSDL_Rect ) : boolean;
+
+implementation
+
+uses
+ Math;
+
+function SDL_PixelTest( SrcSurface1 : PSDL_Surface; SrcRect1 : PSDL_Rect; SrcSurface2 :
+ PSDL_Surface; SrcRect2 : PSDL_Rect; Left1, Top1, Left2, Top2 : integer ) : boolean;
+var
+ Src_Rect1, Src_Rect2 : TSDL_Rect;
+ right1, bottom1 : integer;
+ right2, bottom2 : integer;
+ Scan1Start, Scan2Start, ScanWidth, ScanHeight : cardinal;
+ Mod1, Mod2 : cardinal;
+ Addr1, Addr2 : cardinal;
+ BPP : cardinal;
+ Pitch1, Pitch2 : cardinal;
+ TransparentColor1, TransparentColor2 : cardinal;
+ tx, ty : cardinal;
+ StartTick : cardinal;
+ Color1, Color2 : cardinal;
+begin
+ Result := false;
+ if SrcRect1 = nil then
+ begin
+ with Src_Rect1 do
+ begin
+ x := 0;
+ y := 0;
+ w := SrcSurface1.w;
+ h := SrcSurface1.h;
+ end;
+ end
+ else
+ Src_Rect1 := SrcRect1^;
+ if SrcRect2 = nil then
+ begin
+ with Src_Rect2 do
+ begin
+ x := 0;
+ y := 0;
+ w := SrcSurface2.w;
+ h := SrcSurface2.h;
+ end;
+ end
+ else
+ Src_Rect2 := SrcRect2^;
+ with Src_Rect1 do
+ begin
+ Right1 := Left1 + w;
+ Bottom1 := Top1 + h;
+ end;
+ with Src_Rect2 do
+ begin
+ Right2 := Left2 + w;
+ Bottom2 := Top2 + h;
+ end;
+ if ( Left1 >= Right2 ) or ( Right1 <= Left2 ) or ( Top1 >= Bottom2 ) or ( Bottom1 <=
+ Top2 ) then
+ exit;
+ if Left1 <= Left2 then
+ begin
+ // 1. left, 2. right
+ Scan1Start := Src_Rect1.x + Left2 - Left1;
+ Scan2Start := Src_Rect2.x;
+ ScanWidth := Right1 - Left2;
+ with Src_Rect2 do
+ if ScanWidth > w then
+ ScanWidth := w;
+ end
+ else
+ begin
+ // 1. right, 2. left
+ Scan1Start := Src_Rect1.x;
+ Scan2Start := Src_Rect2.x + Left1 - Left2;
+ ScanWidth := Right2 - Left1;
+ with Src_Rect1 do
+ if ScanWidth > w then
+ ScanWidth := w;
+ end;
+ with SrcSurface1^ do
+ begin
+ Pitch1 := Pitch;
+ Addr1 := cardinal( Pixels );
+ inc( Addr1, Pitch1 * UInt32( Src_Rect1.y ) );
+ with format^ do
+ begin
+ BPP := BytesPerPixel;
+ TransparentColor1 := colorkey;
+ end;
+ end;
+ with SrcSurface2^ do
+ begin
+ TransparentColor2 := format.colorkey;
+ Pitch2 := Pitch;
+ Addr2 := cardinal( Pixels );
+ inc( Addr2, Pitch2 * UInt32( Src_Rect2.y ) );
+ end;
+ Mod1 := Pitch1 - ( ScanWidth * BPP );
+ Mod2 := Pitch2 - ( ScanWidth * BPP );
+ inc( Addr1, BPP * Scan1Start );
+ inc( Addr2, BPP * Scan2Start );
+ if Top1 <= Top2 then
+ begin
+ // 1. up, 2. down
+ ScanHeight := Bottom1 - Top2;
+ if ScanHeight > Src_Rect2.h then
+ ScanHeight := Src_Rect2.h;
+ inc( Addr1, Pitch1 * UInt32( Top2 - Top1 ) );
+ end
+ else
+ begin
+ // 1. down, 2. up
+ ScanHeight := Bottom2 - Top1;
+ if ScanHeight > Src_Rect1.h then
+ ScanHeight := Src_Rect1.h;
+ inc( Addr2, Pitch2 * UInt32( Top1 - Top2 ) );
+ end;
+ case BPP of
+ 1 :
+ for ty := 1 to ScanHeight do
+ begin
+ for tx := 1 to ScanWidth do
+ begin
+ if ( PByte( Addr1 )^ <> TransparentColor1 ) and ( PByte( Addr2 )^ <>
+ TransparentColor2 ) then
+ begin
+ Result := true;
+ exit;
+ end;
+ inc( Addr1 );
+ inc( Addr2 );
+ end;
+ inc( Addr1, Mod1 );
+ inc( Addr2, Mod2 );
+ end;
+ 2 :
+ for ty := 1 to ScanHeight do
+ begin
+ for tx := 1 to ScanWidth do
+ begin
+ if ( PWord( Addr1 )^ <> TransparentColor1 ) and ( PWord( Addr2 )^ <>
+ TransparentColor2 ) then
+ begin
+ Result := true;
+ exit;
+ end;
+ inc( Addr1, 2 );
+ inc( Addr2, 2 );
+ end;
+ inc( Addr1, Mod1 );
+ inc( Addr2, Mod2 );
+ end;
+ 3 :
+ for ty := 1 to ScanHeight do
+ begin
+ for tx := 1 to ScanWidth do
+ begin
+ Color1 := PLongWord( Addr1 )^ and $00FFFFFF;
+ Color2 := PLongWord( Addr2 )^ and $00FFFFFF;
+ if ( Color1 <> TransparentColor1 ) and ( Color2 <> TransparentColor2 )
+ then
+ begin
+ Result := true;
+ exit;
+ end;
+ inc( Addr1, 3 );
+ inc( Addr2, 3 );
+ end;
+ inc( Addr1, Mod1 );
+ inc( Addr2, Mod2 );
+ end;
+ 4 :
+ for ty := 1 to ScanHeight do
+ begin
+ for tx := 1 to ScanWidth do
+ begin
+ if ( PLongWord( Addr1 )^ <> TransparentColor1 ) and ( PLongWord( Addr2 )^ <>
+ TransparentColor2 ) then
+ begin
+ Result := true;
+ exit;
+ end;
+ inc( Addr1, 4 );
+ inc( Addr2, 4 );
+ end;
+ inc( Addr1, Mod1 );
+ inc( Addr2, Mod2 );
+ end;
+ end;
+end;
+
+procedure SDL_AddPixel( DstSurface : PSDL_Surface; x : cardinal; y : cardinal; Color :
+ cardinal );
+var
+ SrcColor : cardinal;
+ Addr : cardinal;
+ R, G, B : cardinal;
+begin
+ if Color = 0 then
+ exit;
+ with DstSurface^ do
+ begin
+ Addr := cardinal( Pixels ) + y * Pitch + x * format.BytesPerPixel;
+ SrcColor := PUInt32( Addr )^;
+ case format.BitsPerPixel of
+ 8 :
+ begin
+ R := SrcColor and $E0 + Color and $E0;
+ G := SrcColor and $1C + Color and $1C;
+ B := SrcColor and $03 + Color and $03;
+ if R > $E0 then
+ R := $E0;
+ if G > $1C then
+ G := $1C;
+ if B > $03 then
+ B := $03;
+ PUInt8( Addr )^ := R or G or B;
+ end;
+ 15 :
+ begin
+ R := SrcColor and $7C00 + Color and $7C00;
+ G := SrcColor and $03E0 + Color and $03E0;
+ B := SrcColor and $001F + Color and $001F;
+ if R > $7C00 then
+ R := $7C00;
+ if G > $03E0 then
+ G := $03E0;
+ if B > $001F then
+ B := $001F;
+ PUInt16( Addr )^ := R or G or B;
+ end;
+ 16 :
+ begin
+ R := SrcColor and $F800 + Color and $F800;
+ G := SrcColor and $07C0 + Color and $07C0;
+ B := SrcColor and $001F + Color and $001F;
+ if R > $F800 then
+ R := $F800;
+ if G > $07C0 then
+ G := $07C0;
+ if B > $001F then
+ B := $001F;
+ PUInt16( Addr )^ := R or G or B;
+ end;
+ 24 :
+ begin
+ R := SrcColor and $00FF0000 + Color and $00FF0000;
+ G := SrcColor and $0000FF00 + Color and $0000FF00;
+ B := SrcColor and $000000FF + Color and $000000FF;
+ if R > $FF0000 then
+ R := $FF0000;
+ if G > $00FF00 then
+ G := $00FF00;
+ if B > $0000FF then
+ B := $0000FF;
+ PUInt32( Addr )^ := SrcColor and $FF000000 or R or G or B;
+ end;
+ 32 :
+ begin
+ R := SrcColor and $00FF0000 + Color and $00FF0000;
+ G := SrcColor and $0000FF00 + Color and $0000FF00;
+ B := SrcColor and $000000FF + Color and $000000FF;
+ if R > $FF0000 then
+ R := $FF0000;
+ if G > $00FF00 then
+ G := $00FF00;
+ if B > $0000FF then
+ B := $0000FF;
+ PUInt32( Addr )^ := R or G or B;
+ end;
+ end;
+ end;
+end;
+
+procedure SDL_SubPixel( DstSurface : PSDL_Surface; x : cardinal; y : cardinal; Color :
+ cardinal );
+var
+ SrcColor : cardinal;
+ Addr : cardinal;
+ R, G, B : cardinal;
+begin
+ if Color = 0 then
+ exit;
+ with DstSurface^ do
+ begin
+ Addr := cardinal( Pixels ) + y * Pitch + x * format.BytesPerPixel;
+ SrcColor := PUInt32( Addr )^;
+ case format.BitsPerPixel of
+ 8 :
+ begin
+ R := SrcColor and $E0 - Color and $E0;
+ G := SrcColor and $1C - Color and $1C;
+ B := SrcColor and $03 - Color and $03;
+ if R > $E0 then
+ R := 0;
+ if G > $1C then
+ G := 0;
+ if B > $03 then
+ B := 0;
+ PUInt8( Addr )^ := R or G or B;
+ end;
+ 15 :
+ begin
+ R := SrcColor and $7C00 - Color and $7C00;
+ G := SrcColor and $03E0 - Color and $03E0;
+ B := SrcColor and $001F - Color and $001F;
+ if R > $7C00 then
+ R := 0;
+ if G > $03E0 then
+ G := 0;
+ if B > $001F then
+ B := 0;
+ PUInt16( Addr )^ := R or G or B;
+ end;
+ 16 :
+ begin
+ R := SrcColor and $F800 - Color and $F800;
+ G := SrcColor and $07C0 - Color and $07C0;
+ B := SrcColor and $001F - Color and $001F;
+ if R > $F800 then
+ R := 0;
+ if G > $07C0 then
+ G := 0;
+ if B > $001F then
+ B := 0;
+ PUInt16( Addr )^ := R or G or B;
+ end;
+ 24 :
+ begin
+ R := SrcColor and $00FF0000 - Color and $00FF0000;
+ G := SrcColor and $0000FF00 - Color and $0000FF00;
+ B := SrcColor and $000000FF - Color and $000000FF;
+ if R > $FF0000 then
+ R := 0;
+ if G > $00FF00 then
+ G := 0;
+ if B > $0000FF then
+ B := 0;
+ PUInt32( Addr )^ := SrcColor and $FF000000 or R or G or B;
+ end;
+ 32 :
+ begin
+ R := SrcColor and $00FF0000 - Color and $00FF0000;
+ G := SrcColor and $0000FF00 - Color and $0000FF00;
+ B := SrcColor and $000000FF - Color and $000000FF;
+ if R > $FF0000 then
+ R := 0;
+ if G > $00FF00 then
+ G := 0;
+ if B > $0000FF then
+ B := 0;
+ PUInt32( Addr )^ := R or G or B;
+ end;
+ end;
+ end;
+end;
+// This procedure works on 8, 15, 16, 24 and 32 bits color depth surfaces.
+// In 8 bit color depth mode the procedure works with the default packed
+// palette (RRRGGGBB). It handles all clipping.
+
+procedure SDL_AddSurface( SrcSurface : PSDL_Surface; SrcRect : PSDL_Rect;
+ DestSurface : PSDL_Surface; DestRect : PSDL_Rect );
+var
+ R, G, B, Pixel1, Pixel2, TransparentColor : cardinal;
+ Src, Dest : TSDL_Rect;
+ Diff : integer;
+ SrcAddr, DestAddr : cardinal;
+ WorkX, WorkY : word;
+ SrcMod, DestMod : cardinal;
+ Bits : cardinal;
+begin
+ if ( SrcSurface = nil ) or ( DestSurface = nil ) then
+ exit; // Remove this to make it faster
+ if ( SrcSurface.Format.BitsPerPixel <> DestSurface.Format.BitsPerPixel ) then
+ exit; // Remove this to make it faster
+ if SrcRect = nil then
+ begin
+ with Src do
+ begin
+ x := 0;
+ y := 0;
+ w := SrcSurface.w;
+ h := SrcSurface.h;
+ end;
+ end
+ else
+ Src := SrcRect^;
+ if DestRect = nil then
+ begin
+ Dest.x := 0;
+ Dest.y := 0;
+ end
+ else
+ Dest := DestRect^;
+ Dest.w := Src.w;
+ Dest.h := Src.h;
+ with DestSurface.Clip_Rect do
+ begin
+ // Source's right side is greater than the dest.cliprect
+ if Dest.x + Src.w > x + w then
+ begin
+ smallint( Src.w ) := x + w - Dest.x;
+ smallint( Dest.w ) := x + w - Dest.x;
+ if smallint( Dest.w ) < 1 then
+ exit;
+ end;
+ // Source's bottom side is greater than the dest.clip
+ if Dest.y + Src.h > y + h then
+ begin
+ smallint( Src.h ) := y + h - Dest.y;
+ smallint( Dest.h ) := y + h - Dest.y;
+ if smallint( Dest.h ) < 1 then
+ exit;
+ end;
+ // Source's left side is less than the dest.clip
+ if Dest.x < x then
+ begin
+ Diff := x - Dest.x;
+ Src.x := Src.x + Diff;
+ smallint( Src.w ) := smallint( Src.w ) - Diff;
+ Dest.x := x;
+ smallint( Dest.w ) := smallint( Dest.w ) - Diff;
+ if smallint( Dest.w ) < 1 then
+ exit;
+ end;
+ // Source's Top side is less than the dest.clip
+ if Dest.y < y then
+ begin
+ Diff := y - Dest.y;
+ Src.y := Src.y + Diff;
+ smallint( Src.h ) := smallint( Src.h ) - Diff;
+ Dest.y := y;
+ smallint( Dest.h ) := smallint( Dest.h ) - Diff;
+ if smallint( Dest.h ) < 1 then
+ exit;
+ end;
+ end;
+ with SrcSurface^ do
+ begin
+ SrcAddr := cardinal( Pixels ) + UInt32( Src.y ) * Pitch + UInt32( Src.x ) *
+ Format.BytesPerPixel;
+ SrcMod := Pitch - Src.w * Format.BytesPerPixel;
+ TransparentColor := Format.colorkey;
+ end;
+ with DestSurface^ do
+ begin
+ DestAddr := cardinal( Pixels ) + UInt32( Dest.y ) * Pitch + UInt32( Dest.x ) *
+ Format.BytesPerPixel;
+ DestMod := Pitch - Dest.w * Format.BytesPerPixel;
+ Bits := Format.BitsPerPixel;
+ end;
+ SDL_LockSurface( SrcSurface );
+ SDL_LockSurface( DestSurface );
+ WorkY := Src.h;
+ case bits of
+ 8 :
+ begin
+ repeat
+ WorkX := Src.w;
+ repeat
+ Pixel1 := PUInt8( SrcAddr )^;
+ if ( Pixel1 <> TransparentColor ) and ( Pixel1 <> 0 ) then
+ begin
+ Pixel2 := PUInt8( DestAddr )^;
+ if Pixel2 > 0 then
+ begin
+ R := Pixel1 and $E0 + Pixel2 and $E0;
+ G := Pixel1 and $1C + Pixel2 and $1C;
+ B := Pixel1 and $03 + Pixel2 and $03;
+ if R > $E0 then
+ R := $E0;
+ if G > $1C then
+ G := $1C;
+ if B > $03 then
+ B := $03;
+ PUInt8( DestAddr )^ := R or G or B;
+ end
+ else
+ PUInt8( DestAddr )^ := Pixel1;
+ end;
+ inc( SrcAddr );
+ inc( DestAddr );
+ dec( WorkX );
+ until WorkX = 0;
+ inc( SrcAddr, SrcMod );
+ inc( DestAddr, DestMod );
+ dec( WorkY );
+ until WorkY = 0;
+ end;
+ 15 :
+ begin
+ repeat
+ WorkX := Src.w;
+ repeat
+ Pixel1 := PUInt16( SrcAddr )^;
+ if ( Pixel1 <> TransparentColor ) and ( Pixel1 <> 0 ) then
+ begin
+ Pixel2 := PUInt16( DestAddr )^;
+ if Pixel2 > 0 then
+ begin
+ R := Pixel1 and $7C00 + Pixel2 and $7C00;
+ G := Pixel1 and $03E0 + Pixel2 and $03E0;
+ B := Pixel1 and $001F + Pixel2 and $001F;
+ if R > $7C00 then
+ R := $7C00;
+ if G > $03E0 then
+ G := $03E0;
+ if B > $001F then
+ B := $001F;
+ PUInt16( DestAddr )^ := R or G or B;
+ end
+ else
+ PUInt16( DestAddr )^ := Pixel1;
+ end;
+ inc( SrcAddr, 2 );
+ inc( DestAddr, 2 );
+ dec( WorkX );
+ until WorkX = 0;
+ inc( SrcAddr, SrcMod );
+ inc( DestAddr, DestMod );
+ dec( WorkY );
+ until WorkY = 0;
+ end;
+ 16 :
+ begin
+ repeat
+ WorkX := Src.w;
+ repeat
+ Pixel1 := PUInt16( SrcAddr )^;
+ if ( Pixel1 <> TransparentColor ) and ( Pixel1 <> 0 ) then
+ begin
+ Pixel2 := PUInt16( DestAddr )^;
+ if Pixel2 > 0 then
+ begin
+ R := Pixel1 and $F800 + Pixel2 and $F800;
+ G := Pixel1 and $07E0 + Pixel2 and $07E0;
+ B := Pixel1 and $001F + Pixel2 and $001F;
+ if R > $F800 then
+ R := $F800;
+ if G > $07E0 then
+ G := $07E0;
+ if B > $001F then
+ B := $001F;
+ PUInt16( DestAddr )^ := R or G or B;
+ end
+ else
+ PUInt16( DestAddr )^ := Pixel1;
+ end;
+ inc( SrcAddr, 2 );
+ inc( DestAddr, 2 );
+ dec( WorkX );
+ until WorkX = 0;
+ inc( SrcAddr, SrcMod );
+ inc( DestAddr, DestMod );
+ dec( WorkY );
+ until WorkY = 0;
+ end;
+ 24 :
+ begin
+ repeat
+ WorkX := Src.w;
+ repeat
+ Pixel1 := PUInt32( SrcAddr )^ and $00FFFFFF;
+ if ( Pixel1 <> TransparentColor ) and ( Pixel1 <> 0 ) then
+ begin
+ Pixel2 := PUInt32( DestAddr )^ and $00FFFFFF;
+ if Pixel2 > 0 then
+ begin
+ R := Pixel1 and $FF0000 + Pixel2 and $FF0000;
+ G := Pixel1 and $00FF00 + Pixel2 and $00FF00;
+ B := Pixel1 and $0000FF + Pixel2 and $0000FF;
+ if R > $FF0000 then
+ R := $FF0000;
+ if G > $00FF00 then
+ G := $00FF00;
+ if B > $0000FF then
+ B := $0000FF;
+ PUInt32( DestAddr )^ := PUInt32( DestAddr )^ and $FF000000 or ( R or G or B );
+ end
+ else
+ PUInt32( DestAddr )^ := PUInt32( DestAddr )^ and $FF000000 or Pixel1;
+ end;
+ inc( SrcAddr, 3 );
+ inc( DestAddr, 3 );
+ dec( WorkX );
+ until WorkX = 0;
+ inc( SrcAddr, SrcMod );
+ inc( DestAddr, DestMod );
+ dec( WorkY );
+ until WorkY = 0;
+ end;
+ 32 :
+ begin
+ repeat
+ WorkX := Src.w;
+ repeat
+ Pixel1 := PUInt32( SrcAddr )^;
+ if ( Pixel1 <> TransparentColor ) and ( Pixel1 <> 0 ) then
+ begin
+ Pixel2 := PUInt32( DestAddr )^;
+ if Pixel2 > 0 then
+ begin
+ R := Pixel1 and $FF0000 + Pixel2 and $FF0000;
+ G := Pixel1 and $00FF00 + Pixel2 and $00FF00;
+ B := Pixel1 and $0000FF + Pixel2 and $0000FF;
+ if R > $FF0000 then
+ R := $FF0000;
+ if G > $00FF00 then
+ G := $00FF00;
+ if B > $0000FF then
+ B := $0000FF;
+ PUInt32( DestAddr )^ := R or G or B;
+ end
+ else
+ PUInt32( DestAddr )^ := Pixel1;
+ end;
+ inc( SrcAddr, 4 );
+ inc( DestAddr, 4 );
+ dec( WorkX );
+ until WorkX = 0;
+ inc( SrcAddr, SrcMod );
+ inc( DestAddr, DestMod );
+ dec( WorkY );
+ until WorkY = 0;
+ end;
+ end;
+ SDL_UnlockSurface( SrcSurface );
+ SDL_UnlockSurface( DestSurface );
+end;
+
+procedure SDL_SubSurface( SrcSurface : PSDL_Surface; SrcRect : PSDL_Rect;
+ DestSurface : PSDL_Surface; DestRect : PSDL_Rect );
+var
+ R, G, B, Pixel1, Pixel2, TransparentColor : cardinal;
+ Src, Dest : TSDL_Rect;
+ Diff : integer;
+ SrcAddr, DestAddr : cardinal;
+ _ebx, _esi, _edi, _esp : cardinal;
+ WorkX, WorkY : word;
+ SrcMod, DestMod : cardinal;
+ Bits : cardinal;
+begin
+ if ( SrcSurface = nil ) or ( DestSurface = nil ) then
+ exit; // Remove this to make it faster
+ if ( SrcSurface.Format.BitsPerPixel <> DestSurface.Format.BitsPerPixel ) then
+ exit; // Remove this to make it faster
+ if SrcRect = nil then
+ begin
+ with Src do
+ begin
+ x := 0;
+ y := 0;
+ w := SrcSurface.w;
+ h := SrcSurface.h;
+ end;
+ end
+ else
+ Src := SrcRect^;
+ if DestRect = nil then
+ begin
+ Dest.x := 0;
+ Dest.y := 0;
+ end
+ else
+ Dest := DestRect^;
+ Dest.w := Src.w;
+ Dest.h := Src.h;
+ with DestSurface.Clip_Rect do
+ begin
+ // Source's right side is greater than the dest.cliprect
+ if Dest.x + Src.w > x + w then
+ begin
+ smallint( Src.w ) := x + w - Dest.x;
+ smallint( Dest.w ) := x + w - Dest.x;
+ if smallint( Dest.w ) < 1 then
+ exit;
+ end;
+ // Source's bottom side is greater than the dest.clip
+ if Dest.y + Src.h > y + h then
+ begin
+ smallint( Src.h ) := y + h - Dest.y;
+ smallint( Dest.h ) := y + h - Dest.y;
+ if smallint( Dest.h ) < 1 then
+ exit;
+ end;
+ // Source's left side is less than the dest.clip
+ if Dest.x < x then
+ begin
+ Diff := x - Dest.x;
+ Src.x := Src.x + Diff;
+ smallint( Src.w ) := smallint( Src.w ) - Diff;
+ Dest.x := x;
+ smallint( Dest.w ) := smallint( Dest.w ) - Diff;
+ if smallint( Dest.w ) < 1 then
+ exit;
+ end;
+ // Source's Top side is less than the dest.clip
+ if Dest.y < y then
+ begin
+ Diff := y - Dest.y;
+ Src.y := Src.y + Diff;
+ smallint( Src.h ) := smallint( Src.h ) - Diff;
+ Dest.y := y;
+ smallint( Dest.h ) := smallint( Dest.h ) - Diff;
+ if smallint( Dest.h ) < 1 then
+ exit;
+ end;
+ end;
+ with SrcSurface^ do
+ begin
+ SrcAddr := cardinal( Pixels ) + UInt32( Src.y ) * Pitch + UInt32( Src.x ) *
+ Format.BytesPerPixel;
+ SrcMod := Pitch - Src.w * Format.BytesPerPixel;
+ TransparentColor := Format.colorkey;
+ end;
+ with DestSurface^ do
+ begin
+ DestAddr := cardinal( Pixels ) + UInt32( Dest.y ) * Pitch + UInt32( Dest.x ) *
+ Format.BytesPerPixel;
+ DestMod := Pitch - Dest.w * Format.BytesPerPixel;
+ Bits := DestSurface.Format.BitsPerPixel;
+ end;
+ SDL_LockSurface( SrcSurface );
+ SDL_LockSurface( DestSurface );
+ WorkY := Src.h;
+ case bits of
+ 8 :
+ begin
+ repeat
+ WorkX := Src.w;
+ repeat
+ Pixel1 := PUInt8( SrcAddr )^;
+ if ( Pixel1 <> TransparentColor ) and ( Pixel1 <> 0 ) then
+ begin
+ Pixel2 := PUInt8( DestAddr )^;
+ if Pixel2 > 0 then
+ begin
+ R := Pixel2 and $E0 - Pixel1 and $E0;
+ G := Pixel2 and $1C - Pixel1 and $1C;
+ B := Pixel2 and $03 - Pixel1 and $03;
+ if R > $E0 then
+ R := 0;
+ if G > $1C then
+ G := 0;
+ if B > $03 then
+ B := 0;
+ PUInt8( DestAddr )^ := R or G or B;
+ end;
+ end;
+ inc( SrcAddr );
+ inc( DestAddr );
+ dec( WorkX );
+ until WorkX = 0;
+ inc( SrcAddr, SrcMod );
+ inc( DestAddr, DestMod );
+ dec( WorkY );
+ until WorkY = 0;
+ end;
+ 15 :
+ begin
+ repeat
+ WorkX := Src.w;
+ repeat
+ Pixel1 := PUInt16( SrcAddr )^;
+ if ( Pixel1 <> TransparentColor ) and ( Pixel1 <> 0 ) then
+ begin
+ Pixel2 := PUInt16( DestAddr )^;
+ if Pixel2 > 0 then
+ begin
+ R := Pixel2 and $7C00 - Pixel1 and $7C00;
+ G := Pixel2 and $03E0 - Pixel1 and $03E0;
+ B := Pixel2 and $001F - Pixel1 and $001F;
+ if R > $7C00 then
+ R := 0;
+ if G > $03E0 then
+ G := 0;
+ if B > $001F then
+ B := 0;
+ PUInt16( DestAddr )^ := R or G or B;
+ end;
+ end;
+ inc( SrcAddr, 2 );
+ inc( DestAddr, 2 );
+ dec( WorkX );
+ until WorkX = 0;
+ inc( SrcAddr, SrcMod );
+ inc( DestAddr, DestMod );
+ dec( WorkY );
+ until WorkY = 0;
+ end;
+ 16 :
+ begin
+ repeat
+ WorkX := Src.w;
+ repeat
+ Pixel1 := PUInt16( SrcAddr )^;
+ if ( Pixel1 <> TransparentColor ) and ( Pixel1 <> 0 ) then
+ begin
+ Pixel2 := PUInt16( DestAddr )^;
+ if Pixel2 > 0 then
+ begin
+ R := Pixel2 and $F800 - Pixel1 and $F800;
+ G := Pixel2 and $07E0 - Pixel1 and $07E0;
+ B := Pixel2 and $001F - Pixel1 and $001F;
+ if R > $F800 then
+ R := 0;
+ if G > $07E0 then
+ G := 0;
+ if B > $001F then
+ B := 0;
+ PUInt16( DestAddr )^ := R or G or B;
+ end;
+ end;
+ inc( SrcAddr, 2 );
+ inc( DestAddr, 2 );
+ dec( WorkX );
+ until WorkX = 0;
+ inc( SrcAddr, SrcMod );
+ inc( DestAddr, DestMod );
+ dec( WorkY );
+ until WorkY = 0;
+ end;
+ 24 :
+ begin
+ repeat
+ WorkX := Src.w;
+ repeat
+ Pixel1 := PUInt32( SrcAddr )^ and $00FFFFFF;
+ if ( Pixel1 <> TransparentColor ) and ( Pixel1 <> 0 ) then
+ begin
+ Pixel2 := PUInt32( DestAddr )^ and $00FFFFFF;
+ if Pixel2 > 0 then
+ begin
+ R := Pixel2 and $FF0000 - Pixel1 and $FF0000;
+ G := Pixel2 and $00FF00 - Pixel1 and $00FF00;
+ B := Pixel2 and $0000FF - Pixel1 and $0000FF;
+ if R > $FF0000 then
+ R := 0;
+ if G > $00FF00 then
+ G := 0;
+ if B > $0000FF then
+ B := 0;
+ PUInt32( DestAddr )^ := PUInt32( DestAddr )^ and $FF000000 or ( R or G or B );
+ end;
+ end;
+ inc( SrcAddr, 3 );
+ inc( DestAddr, 3 );
+ dec( WorkX );
+ until WorkX = 0;
+ inc( SrcAddr, SrcMod );
+ inc( DestAddr, DestMod );
+ dec( WorkY );
+ until WorkY = 0;
+ end;
+ 32 :
+ begin
+ repeat
+ WorkX := Src.w;
+ repeat
+ Pixel1 := PUInt32( SrcAddr )^;
+ if ( Pixel1 <> TransparentColor ) and ( Pixel1 <> 0 ) then
+ begin
+ Pixel2 := PUInt32( DestAddr )^;
+ if Pixel2 > 0 then
+ begin
+ R := Pixel2 and $FF0000 - Pixel1 and $FF0000;
+ G := Pixel2 and $00FF00 - Pixel1 and $00FF00;
+ B := Pixel2 and $0000FF - Pixel1 and $0000FF;
+ if R > $FF0000 then
+ R := 0;
+ if G > $00FF00 then
+ G := 0;
+ if B > $0000FF then
+ B := 0;
+ PUInt32( DestAddr )^ := R or G or B;
+ end
+ else
+ PUInt32( DestAddr )^ := Pixel2;
+ end;
+ inc( SrcAddr, 4 );
+ inc( DestAddr, 4 );
+ dec( WorkX );
+ until WorkX = 0;
+ inc( SrcAddr, SrcMod );
+ inc( DestAddr, DestMod );
+ dec( WorkY );
+ until WorkY = 0;
+ end;
+ end;
+ SDL_UnlockSurface( SrcSurface );
+ SDL_UnlockSurface( DestSurface );
+end;
+
+procedure SDL_MonoSurface( SrcSurface : PSDL_Surface; SrcRect : PSDL_Rect;
+ DestSurface : PSDL_Surface; DestRect : PSDL_Rect; Color : cardinal );
+var
+ Src, Dest : TSDL_Rect;
+ Diff : integer;
+ SrcAddr, DestAddr : cardinal;
+ _ebx, _esi, _edi, _esp : cardinal;
+ WorkX, WorkY : word;
+ SrcMod, DestMod : cardinal;
+ TransparentColor, SrcColor : cardinal;
+ BPP : cardinal;
+begin
+ if ( SrcSurface = nil ) or ( DestSurface = nil ) then
+ exit; // Remove this to make it faster
+ if ( SrcSurface.Format.BitsPerPixel <> DestSurface.Format.BitsPerPixel ) then
+ exit; // Remove this to make it faster
+ if SrcRect = nil then
+ begin
+ with Src do
+ begin
+ x := 0;
+ y := 0;
+ w := SrcSurface.w;
+ h := SrcSurface.h;
+ end;
+ end
+ else
+ Src := SrcRect^;
+ if DestRect = nil then
+ begin
+ Dest.x := 0;
+ Dest.y := 0;
+ end
+ else
+ Dest := DestRect^;
+ Dest.w := Src.w;
+ Dest.h := Src.h;
+ with DestSurface.Clip_Rect do
+ begin
+ // Source's right side is greater than the dest.cliprect
+ if Dest.x + Src.w > x + w then
+ begin
+ smallint( Src.w ) := x + w - Dest.x;
+ smallint( Dest.w ) := x + w - Dest.x;
+ if smallint( Dest.w ) < 1 then
+ exit;
+ end;
+ // Source's bottom side is greater than the dest.clip
+ if Dest.y + Src.h > y + h then
+ begin
+ smallint( Src.h ) := y + h - Dest.y;
+ smallint( Dest.h ) := y + h - Dest.y;
+ if smallint( Dest.h ) < 1 then
+ exit;
+ end;
+ // Source's left side is less than the dest.clip
+ if Dest.x < x then
+ begin
+ Diff := x - Dest.x;
+ Src.x := Src.x + Diff;
+ smallint( Src.w ) := smallint( Src.w ) - Diff;
+ Dest.x := x;
+ smallint( Dest.w ) := smallint( Dest.w ) - Diff;
+ if smallint( Dest.w ) < 1 then
+ exit;
+ end;
+ // Source's Top side is less than the dest.clip
+ if Dest.y < y then
+ begin
+ Diff := y - Dest.y;
+ Src.y := Src.y + Diff;
+ smallint( Src.h ) := smallint( Src.h ) - Diff;
+ Dest.y := y;
+ smallint( Dest.h ) := smallint( Dest.h ) - Diff;
+ if smallint( Dest.h ) < 1 then
+ exit;
+ end;
+ end;
+ with SrcSurface^ do
+ begin
+ SrcAddr := cardinal( Pixels ) + UInt32( Src.y ) * Pitch + UInt32( Src.x ) *
+ Format.BytesPerPixel;
+ SrcMod := Pitch - Src.w * Format.BytesPerPixel;
+ TransparentColor := Format.colorkey;
+ end;
+ with DestSurface^ do
+ begin
+ DestAddr := cardinal( Pixels ) + UInt32( Dest.y ) * Pitch + UInt32( Dest.x ) *
+ Format.BytesPerPixel;
+ DestMod := Pitch - Dest.w * Format.BytesPerPixel;
+ BPP := DestSurface.Format.BytesPerPixel;
+ end;
+ SDL_LockSurface( SrcSurface );
+ SDL_LockSurface( DestSurface );
+ WorkY := Src.h;
+ case BPP of
+ 1 :
+ begin
+ repeat
+ WorkX := Src.w;
+ repeat
+ SrcColor := PUInt8( SrcAddr )^;
+ if SrcColor <> TransparentColor then
+ PUInt8( DestAddr )^ := SrcColor;
+ inc( SrcAddr );
+ inc( DestAddr );
+ dec( WorkX );
+ until WorkX = 0;
+ inc( SrcAddr, SrcMod );
+ inc( DestAddr, DestMod );
+ dec( WorkY );
+ until WorkY = 0;
+ end;
+ 2 :
+ begin
+ repeat
+ WorkX := Src.w;
+ repeat
+ SrcColor := PUInt16( SrcAddr )^;
+ if SrcColor <> TransparentColor then
+ PUInt16( DestAddr )^ := SrcColor;
+ inc( SrcAddr );
+ inc( DestAddr );
+ dec( WorkX );
+ until WorkX = 0;
+ inc( SrcAddr, SrcMod );
+ inc( DestAddr, DestMod );
+ dec( WorkY );
+ until WorkY = 0;
+ end;
+ 3 :
+ begin
+ repeat
+ WorkX := Src.w;
+ repeat
+ SrcColor := PUInt32( SrcAddr )^ and $FFFFFF;
+ if SrcColor <> TransparentColor then
+ PUInt32( DestAddr )^ := ( PUInt32( DestAddr )^ and $FFFFFF ) or SrcColor;
+ inc( SrcAddr );
+ inc( DestAddr );
+ dec( WorkX );
+ until WorkX = 0;
+ inc( SrcAddr, SrcMod );
+ inc( DestAddr, DestMod );
+ dec( WorkY );
+ until WorkY = 0;
+ end;
+ 4 :
+ begin
+ repeat
+ WorkX := Src.w;
+ repeat
+ SrcColor := PUInt32( SrcAddr )^;
+ if SrcColor <> TransparentColor then
+ PUInt32( DestAddr )^ := SrcColor;
+ inc( SrcAddr );
+ inc( DestAddr );
+ dec( WorkX );
+ until WorkX = 0;
+ inc( SrcAddr, SrcMod );
+ inc( DestAddr, DestMod );
+ dec( WorkY );
+ until WorkY = 0;
+ end;
+ end;
+ SDL_UnlockSurface( SrcSurface );
+ SDL_UnlockSurface( DestSurface );
+end;
+// TextureRect.w and TextureRect.h are not used.
+// The TextureSurface's size MUST larger than the drawing rectangle!!!
+
+procedure SDL_TexturedSurface( SrcSurface : PSDL_Surface; SrcRect : PSDL_Rect;
+ DestSurface : PSDL_Surface; DestRect : PSDL_Rect; Texture : PSDL_Surface;
+ TextureRect : PSDL_Rect );
+var
+ Src, Dest : TSDL_Rect;
+ Diff : integer;
+ SrcAddr, DestAddr, TextAddr : cardinal;
+ _ebx, _esi, _edi, _esp : cardinal;
+ WorkX, WorkY : word;
+ SrcMod, DestMod, TextMod : cardinal;
+ SrcColor, TransparentColor, TextureColor : cardinal;
+ BPP : cardinal;
+begin
+ if ( SrcSurface = nil ) or ( DestSurface = nil ) then
+ exit; // Remove this to make it faster
+ if ( SrcSurface.Format.BitsPerPixel <> DestSurface.Format.BitsPerPixel ) then
+ exit; // Remove this to make it faster
+ if SrcRect = nil then
+ begin
+ with Src do
+ begin
+ x := 0;
+ y := 0;
+ w := SrcSurface.w;
+ h := SrcSurface.h;
+ end;
+ end
+ else
+ Src := SrcRect^;
+ if DestRect = nil then
+ begin
+ Dest.x := 0;
+ Dest.y := 0;
+ end
+ else
+ Dest := DestRect^;
+ Dest.w := Src.w;
+ Dest.h := Src.h;
+ with DestSurface.Clip_Rect do
+ begin
+ // Source's right side is greater than the dest.cliprect
+ if Dest.x + Src.w > x + w then
+ begin
+ smallint( Src.w ) := x + w - Dest.x;
+ smallint( Dest.w ) := x + w - Dest.x;
+ if smallint( Dest.w ) < 1 then
+ exit;
+ end;
+ // Source's bottom side is greater than the dest.clip
+ if Dest.y + Src.h > y + h then
+ begin
+ smallint( Src.h ) := y + h - Dest.y;
+ smallint( Dest.h ) := y + h - Dest.y;
+ if smallint( Dest.h ) < 1 then
+ exit;
+ end;
+ // Source's left side is less than the dest.clip
+ if Dest.x < x then
+ begin
+ Diff := x - Dest.x;
+ Src.x := Src.x + Diff;
+ smallint( Src.w ) := smallint( Src.w ) - Diff;
+ Dest.x := x;
+ smallint( Dest.w ) := smallint( Dest.w ) - Diff;
+ if smallint( Dest.w ) < 1 then
+ exit;
+ end;
+ // Source's Top side is less than the dest.clip
+ if Dest.y < y then
+ begin
+ Diff := y - Dest.y;
+ Src.y := Src.y + Diff;
+ smallint( Src.h ) := smallint( Src.h ) - Diff;
+ Dest.y := y;
+ smallint( Dest.h ) := smallint( Dest.h ) - Diff;
+ if smallint( Dest.h ) < 1 then
+ exit;
+ end;
+ end;
+ with SrcSurface^ do
+ begin
+ SrcAddr := cardinal( Pixels ) + UInt32( Src.y ) * Pitch + UInt32( Src.x ) *
+ Format.BytesPerPixel;
+ SrcMod := Pitch - Src.w * Format.BytesPerPixel;
+ TransparentColor := format.colorkey;
+ end;
+ with DestSurface^ do
+ begin
+ DestAddr := cardinal( Pixels ) + UInt32( Dest.y ) * Pitch + UInt32( Dest.x ) *
+ Format.BytesPerPixel;
+ DestMod := Pitch - Dest.w * Format.BytesPerPixel;
+ BPP := DestSurface.Format.BitsPerPixel;
+ end;
+ with Texture^ do
+ begin
+ TextAddr := cardinal( Pixels ) + UInt32( TextureRect.y ) * Pitch +
+ UInt32( TextureRect.x ) * Format.BytesPerPixel;
+ TextMod := Pitch - Src.w * Format.BytesPerPixel;
+ end;
+ SDL_LockSurface( SrcSurface );
+ SDL_LockSurface( DestSurface );
+ SDL_LockSurface( Texture );
+ WorkY := Src.h;
+ case BPP of
+ 1 :
+ begin
+ repeat
+ WorkX := Src.w;
+ repeat
+ SrcColor := PUInt8( SrcAddr )^;
+ if SrcColor <> TransparentColor then
+ PUInt8( DestAddr )^ := PUint8( TextAddr )^;
+ inc( SrcAddr );
+ inc( DestAddr );
+ inc( TextAddr );
+ dec( WorkX );
+ until WorkX = 0;
+ inc( SrcAddr, SrcMod );
+ inc( DestAddr, DestMod );
+ inc( TextAddr, TextMod );
+ dec( WorkY );
+ until WorkY = 0;
+ end;
+ 2 :
+ begin
+ repeat
+ WorkX := Src.w;
+ repeat
+ SrcColor := PUInt16( SrcAddr )^;
+ if SrcColor <> TransparentColor then
+ PUInt16( DestAddr )^ := PUInt16( TextAddr )^;
+ inc( SrcAddr );
+ inc( DestAddr );
+ inc( TextAddr );
+ dec( WorkX );
+ until WorkX = 0;
+ inc( SrcAddr, SrcMod );
+ inc( DestAddr, DestMod );
+ inc( TextAddr, TextMod );
+ dec( WorkY );
+ until WorkY = 0;
+ end;
+ 3 :
+ begin
+ repeat
+ WorkX := Src.w;
+ repeat
+ SrcColor := PUInt32( SrcAddr )^ and $FFFFFF;
+ if SrcColor <> TransparentColor then
+ PUInt32( DestAddr )^ := ( PUInt32( DestAddr )^ and $FFFFFF ) or ( PUInt32( TextAddr )^ and $FFFFFF );
+ inc( SrcAddr );
+ inc( DestAddr );
+ inc( TextAddr );
+ dec( WorkX );
+ until WorkX = 0;
+ inc( SrcAddr, SrcMod );
+ inc( DestAddr, DestMod );
+ inc( TextAddr, TextMod );
+ dec( WorkY );
+ until WorkY = 0;
+ end;
+ 4 :
+ begin
+ repeat
+ WorkX := Src.w;
+ repeat
+ SrcColor := PUInt32( SrcAddr )^;
+ if SrcColor <> TransparentColor then
+ PUInt32( DestAddr )^ := PUInt32( TextAddr )^;
+ inc( SrcAddr );
+ inc( DestAddr );
+ inc( TextAddr );
+ dec( WorkX );
+ until WorkX = 0;
+ inc( SrcAddr, SrcMod );
+ inc( DestAddr, DestMod );
+ inc( TextAddr, TextMod );
+ dec( WorkY );
+ until WorkY = 0;
+ end;
+ end;
+ SDL_UnlockSurface( SrcSurface );
+ SDL_UnlockSurface( DestSurface );
+ SDL_UnlockSurface( Texture );
+end;
+
+procedure SDL_ZoomSurface( SrcSurface : PSDL_Surface; SrcRect : PSDL_Rect; DstSurface : PSDL_Surface; DstRect : PSDL_Rect );
+var
+ xc, yc : cardinal;
+ rx, wx, ry, wy, ry16 : cardinal;
+ color : cardinal;
+ modx, mody : cardinal;
+begin
+ // Warning! No checks for surface pointers!!!
+ if srcrect = nil then
+ srcrect := @SrcSurface.clip_rect;
+ if dstrect = nil then
+ dstrect := @DstSurface.clip_rect;
+ if SDL_MustLock( SrcSurface ) then
+ SDL_LockSurface( SrcSurface );
+ if SDL_MustLock( DstSurface ) then
+ SDL_LockSurface( DstSurface );
+ modx := trunc( ( srcrect.w / dstrect.w ) * 65536 );
+ mody := trunc( ( srcrect.h / dstrect.h ) * 65536 );
+ //rx := srcrect.x * 65536;
+ ry := srcrect.y * 65536;
+ wy := dstrect.y;
+ for yc := 0 to dstrect.h - 1 do
+ begin
+ rx := srcrect.x * 65536;
+ wx := dstrect.x;
+ ry16 := ry shr 16;
+ for xc := 0 to dstrect.w - 1 do
+ begin
+ color := SDL_GetPixel( SrcSurface, rx shr 16, ry16 );
+ SDL_PutPixel( DstSurface, wx, wy, color );
+ rx := rx + modx;
+ inc( wx );
+ end;
+ ry := ry + mody;
+ inc( wy );
+ end;
+ if SDL_MustLock( SrcSurface ) then
+ SDL_UnlockSurface( SrcSurface );
+ if SDL_MustLock( DstSurface ) then
+ SDL_UnlockSurface( DstSurface );
+end;
+// Re-map a rectangular area into an area defined by four vertices
+// Converted from C to Pascal by KiCHY
+
+procedure SDL_WarpSurface( SrcSurface : PSDL_Surface; SrcRect : PSDL_Rect; DstSurface : PSDL_Surface; UL, UR, LR, LL : PPoint );
+const
+ SHIFTS = 15; // Extend ints to limit round-off error (try 2 - 20)
+ THRESH = 1 shl SHIFTS; // Threshold for pixel size value
+ procedure CopySourceToDest( UL, UR, LR, LL : TPoint; x1, y1, x2, y2 : cardinal );
+ var
+ tm, lm, rm, bm, m : TPoint;
+ mx, my : cardinal;
+ cr : cardinal;
+ begin
+ // Does the destination area specify a single pixel?
+ if ( ( abs( ul.x - ur.x ) < THRESH ) and
+ ( abs( ul.x - lr.x ) < THRESH ) and
+ ( abs( ul.x - ll.x ) < THRESH ) and
+ ( abs( ul.y - ur.y ) < THRESH ) and
+ ( abs( ul.y - lr.y ) < THRESH ) and
+ ( abs( ul.y - ll.y ) < THRESH ) ) then
+ begin // Yes
+ cr := SDL_GetPixel( SrcSurface, ( x1 shr SHIFTS ), ( y1 shr SHIFTS ) );
+ SDL_PutPixel( DstSurface, ( ul.x shr SHIFTS ), ( ul.y shr SHIFTS ), cr );
+ end
+ else
+ begin // No
+ // Quarter the source and the destination, and then recurse
+ tm.x := ( ul.x + ur.x ) shr 1;
+ tm.y := ( ul.y + ur.y ) shr 1;
+ bm.x := ( ll.x + lr.x ) shr 1;
+ bm.y := ( ll.y + lr.y ) shr 1;
+ lm.x := ( ul.x + ll.x ) shr 1;
+ lm.y := ( ul.y + ll.y ) shr 1;
+ rm.x := ( ur.x + lr.x ) shr 1;
+ rm.y := ( ur.y + lr.y ) shr 1;
+ m.x := ( tm.x + bm.x ) shr 1;
+ m.y := ( tm.y + bm.y ) shr 1;
+ mx := ( x1 + x2 ) shr 1;
+ my := ( y1 + y2 ) shr 1;
+ CopySourceToDest( ul, tm, m, lm, x1, y1, mx, my );
+ CopySourceToDest( tm, ur, rm, m, mx, y1, x2, my );
+ CopySourceToDest( m, rm, lr, bm, mx, my, x2, y2 );
+ CopySourceToDest( lm, m, bm, ll, x1, my, mx, y2 );
+ end;
+ end;
+var
+ _UL, _UR, _LR, _LL : TPoint;
+ Rect_x, Rect_y, Rect_w, Rect_h : integer;
+begin
+ if SDL_MustLock( SrcSurface ) then
+ SDL_LockSurface( SrcSurface );
+ if SDL_MustLock( DstSurface ) then
+ SDL_LockSurface( DstSurface );
+ if SrcRect = nil then
+ begin
+ Rect_x := 0;
+ Rect_y := 0;
+ Rect_w := ( SrcSurface.w - 1 ) shl SHIFTS;
+ Rect_h := ( SrcSurface.h - 1 ) shl SHIFTS;
+ end
+ else
+ begin
+ Rect_x := SrcRect.x;
+ Rect_y := SrcRect.y;
+ Rect_w := ( SrcRect.w - 1 ) shl SHIFTS;
+ Rect_h := ( SrcRect.h - 1 ) shl SHIFTS;
+ end;
+ // Shift all values to help reduce round-off error.
+ _ul.x := ul.x shl SHIFTS;
+ _ul.y := ul.y shl SHIFTS;
+ _ur.x := ur.x shl SHIFTS;
+ _ur.y := ur.y shl SHIFTS;
+ _lr.x := lr.x shl SHIFTS;
+ _lr.y := lr.y shl SHIFTS;
+ _ll.x := ll.x shl SHIFTS;
+ _ll.y := ll.y shl SHIFTS;
+ CopySourceToDest( _ul, _ur, _lr, _ll, Rect_x, Rect_y, Rect_w, Rect_h );
+ if SDL_MustLock( SrcSurface ) then
+ SDL_UnlockSurface( SrcSurface );
+ if SDL_MustLock( DstSurface ) then
+ SDL_UnlockSurface( DstSurface );
+end;
+
+// Draw a line between x1,y1 and x2,y2 to the given surface
+// NOTE: The surface must be locked before calling this!
+
+procedure SDL_DrawLine( DstSurface : PSDL_Surface; x1, y1, x2, y2 : integer; Color :
+ cardinal );
+var
+ dx, dy, sdx, sdy, x, y, px, py : integer;
+begin
+ dx := x2 - x1;
+ dy := y2 - y1;
+ if dx < 0 then
+ sdx := -1
+ else
+ sdx := 1;
+ if dy < 0 then
+ sdy := -1
+ else
+ sdy := 1;
+ dx := sdx * dx + 1;
+ dy := sdy * dy + 1;
+ x := 0;
+ y := 0;
+ px := x1;
+ py := y1;
+ if dx >= dy then
+ begin
+ for x := 0 to dx - 1 do
+ begin
+ SDL_PutPixel( DstSurface, px, py, Color );
+ y := y + dy;
+ if y >= dx then
+ begin
+ y := y - dx;
+ py := py + sdy;
+ end;
+ px := px + sdx;
+ end;
+ end
+ else
+ begin
+ for y := 0 to dy - 1 do
+ begin
+ SDL_PutPixel( DstSurface, px, py, Color );
+ x := x + dx;
+ if x >= dy then
+ begin
+ x := x - dy;
+ px := px + sdx;
+ end;
+ py := py + sdy;
+ end;
+ end;
+end;
+
+// Draw a dashed line between x1,y1 and x2,y2 to the given surface
+// NOTE: The surface must be locked before calling this!
+
+procedure SDL_DrawLine( DstSurface : PSDL_Surface; x1, y1, x2, y2 : integer; Color :
+ cardinal; DashLength, DashSpace : byte ); overload;
+var
+ dx, dy, sdx, sdy, x, y, px, py, counter : integer; drawdash : boolean;
+begin
+ counter := 0;
+ drawdash := true; //begin line drawing with dash
+
+ //Avoid invalid user-passed dash parameters
+ if ( DashLength < 1 )
+ then
+ DashLength := 1;
+ if ( DashSpace < 1 )
+ then
+ DashSpace := 0;
+
+ dx := x2 - x1;
+ dy := y2 - y1;
+ if dx < 0 then
+ sdx := -1
+ else
+ sdx := 1;
+ if dy < 0 then
+ sdy := -1
+ else
+ sdy := 1;
+ dx := sdx * dx + 1;
+ dy := sdy * dy + 1;
+ x := 0;
+ y := 0;
+ px := x1;
+ py := y1;
+ if dx >= dy then
+ begin
+ for x := 0 to dx - 1 do
+ begin
+
+ //Alternate drawing dashes, or leaving spaces
+ if drawdash then
+ begin
+ SDL_PutPixel( DstSurface, px, py, Color );
+ inc( counter );
+ if ( counter > DashLength - 1 ) and ( DashSpace > 0 ) then
+ begin
+ drawdash := false;
+ counter := 0;
+ end;
+ end
+ else //space
+ begin
+ inc( counter );
+ if counter > DashSpace - 1 then
+ begin
+ drawdash := true;
+ counter := 0;
+ end;
+ end;
+
+ y := y + dy;
+ if y >= dx then
+ begin
+ y := y - dx;
+ py := py + sdy;
+ end;
+ px := px + sdx;
+ end;
+ end
+ else
+ begin
+ for y := 0 to dy - 1 do
+ begin
+
+ //Alternate drawing dashes, or leaving spaces
+ if drawdash then
+ begin
+ SDL_PutPixel( DstSurface, px, py, Color );
+ inc( counter );
+ if ( counter > DashLength - 1 ) and ( DashSpace > 0 ) then
+ begin
+ drawdash := false;
+ counter := 0;
+ end;
+ end
+ else //space
+ begin
+ inc( counter );
+ if counter > DashSpace - 1 then
+ begin
+ drawdash := true;
+ counter := 0;
+ end;
+ end;
+
+ x := x + dx;
+ if x >= dy then
+ begin
+ x := x - dy;
+ px := px + sdx;
+ end;
+ py := py + sdy;
+ end;
+ end;
+end;
+
+procedure SDL_AddLine( DstSurface : PSDL_Surface; x1, y1, x2, y2 : integer; Color :
+ cardinal );
+var
+ dx, dy, sdx, sdy, x, y, px, py : integer;
+begin
+ dx := x2 - x1;
+ dy := y2 - y1;
+ if dx < 0 then
+ sdx := -1
+ else
+ sdx := 1;
+ if dy < 0 then
+ sdy := -1
+ else
+ sdy := 1;
+ dx := sdx * dx + 1;
+ dy := sdy * dy + 1;
+ x := 0;
+ y := 0;
+ px := x1;
+ py := y1;
+ if dx >= dy then
+ begin
+ for x := 0 to dx - 1 do
+ begin
+ SDL_AddPixel( DstSurface, px, py, Color );
+ y := y + dy;
+ if y >= dx then
+ begin
+ y := y - dx;
+ py := py + sdy;
+ end;
+ px := px + sdx;
+ end;
+ end
+ else
+ begin
+ for y := 0 to dy - 1 do
+ begin
+ SDL_AddPixel( DstSurface, px, py, Color );
+ x := x + dx;
+ if x >= dy then
+ begin
+ x := x - dy;
+ px := px + sdx;
+ end;
+ py := py + sdy;
+ end;
+ end;
+end;
+
+procedure SDL_SubLine( DstSurface : PSDL_Surface; x1, y1, x2, y2 : integer; Color :
+ cardinal );
+var
+ dx, dy, sdx, sdy, x, y, px, py : integer;
+begin
+ dx := x2 - x1;
+ dy := y2 - y1;
+ if dx < 0 then
+ sdx := -1
+ else
+ sdx := 1;
+ if dy < 0 then
+ sdy := -1
+ else
+ sdy := 1;
+ dx := sdx * dx + 1;
+ dy := sdy * dy + 1;
+ x := 0;
+ y := 0;
+ px := x1;
+ py := y1;
+ if dx >= dy then
+ begin
+ for x := 0 to dx - 1 do
+ begin
+ SDL_SubPixel( DstSurface, px, py, Color );
+ y := y + dy;
+ if y >= dx then
+ begin
+ y := y - dx;
+ py := py + sdy;
+ end;
+ px := px + sdx;
+ end;
+ end
+ else
+ begin
+ for y := 0 to dy - 1 do
+ begin
+ SDL_SubPixel( DstSurface, px, py, Color );
+ x := x + dx;
+ if x >= dy then
+ begin
+ x := x - dy;
+ px := px + sdx;
+ end;
+ py := py + sdy;
+ end;
+ end;
+end;
+
+// flips a rectangle vertically on given surface
+
+procedure SDL_FlipRectV( DstSurface : PSDL_Surface; Rect : PSDL_Rect );
+var
+ TmpRect : TSDL_Rect;
+ Locked : boolean;
+ y, FlipLength, RowLength : integer;
+ Row1, Row2 : Pointer;
+ OneRow : TByteArray; // Optimize it if you wish
+begin
+ if DstSurface <> nil then
+ begin
+ if Rect = nil then
+ begin // if Rect=nil then we flip the whole surface
+ TmpRect := SDLRect( 0, 0, DstSurface.w, DstSurface.h );
+ Rect := @TmpRect;
+ end;
+ FlipLength := Rect^.h shr 1 - 1;
+ RowLength := Rect^.w * DstSurface^.format.BytesPerPixel;
+ if SDL_MustLock( DstSurface ) then
+ begin
+ Locked := true;
+ SDL_LockSurface( DstSurface );
+ end
+ else
+ Locked := false;
+ Row1 := pointer( cardinal( DstSurface^.Pixels ) + UInt32( Rect^.y ) *
+ DstSurface^.Pitch );
+ Row2 := pointer( cardinal( DstSurface^.Pixels ) + ( UInt32( Rect^.y ) + Rect^.h - 1 )
+ * DstSurface^.Pitch );
+ for y := 0 to FlipLength do
+ begin
+ Move( Row1^, OneRow, RowLength );
+ Move( Row2^, Row1^, RowLength );
+ Move( OneRow, Row2^, RowLength );
+ inc( cardinal( Row1 ), DstSurface^.Pitch );
+ dec( cardinal( Row2 ), DstSurface^.Pitch );
+ end;
+ if Locked then
+ SDL_UnlockSurface( DstSurface );
+ end;
+end;
+
+// flips a rectangle horizontally on given surface
+
+procedure SDL_FlipRectH( DstSurface : PSDL_Surface; Rect : PSDL_Rect );
+type
+ T24bit = packed array[ 0..2 ] of byte;
+ T24bitArray = packed array[ 0..8191 ] of T24bit;
+ P24bitArray = ^T24bitArray;
+ TLongWordArray = array[ 0..8191 ] of LongWord;
+ PLongWordArray = ^TLongWordArray;
+var
+ TmpRect : TSDL_Rect;
+ Row8bit : PByteArray;
+ Row16bit : PWordArray;
+ Row24bit : P24bitArray;
+ Row32bit : PLongWordArray;
+ y, x, RightSide, FlipLength : integer;
+ Pixel : cardinal;
+ Pixel24 : T24bit;
+ Locked : boolean;
+begin
+ if DstSurface <> nil then
+ begin
+ if Rect = nil then
+ begin
+ TmpRect := SDLRect( 0, 0, DstSurface.w, DstSurface.h );
+ Rect := @TmpRect;
+ end;
+ FlipLength := Rect^.w shr 1 - 1;
+ if SDL_MustLock( DstSurface ) then
+ begin
+ Locked := true;
+ SDL_LockSurface( DstSurface );
+ end
+ else
+ Locked := false;
+ case DstSurface^.format.BytesPerPixel of
+ 1 :
+ begin
+ Row8Bit := pointer( cardinal( DstSurface^.pixels ) + UInt32( Rect^.y ) *
+ DstSurface^.pitch );
+ for y := 1 to Rect^.h do
+ begin
+ RightSide := Rect^.w - 1;
+ for x := 0 to FlipLength do
+ begin
+ Pixel := Row8Bit^[ x ];
+ Row8Bit^[ x ] := Row8Bit^[ RightSide ];
+ Row8Bit^[ RightSide ] := Pixel;
+ dec( RightSide );
+ end;
+ inc( cardinal( Row8Bit ), DstSurface^.pitch );
+ end;
+ end;
+ 2 :
+ begin
+ Row16Bit := pointer( cardinal( DstSurface^.pixels ) + UInt32( Rect^.y ) *
+ DstSurface^.pitch );
+ for y := 1 to Rect^.h do
+ begin
+ RightSide := Rect^.w - 1;
+ for x := 0 to FlipLength do
+ begin
+ Pixel := Row16Bit^[ x ];
+ Row16Bit^[ x ] := Row16Bit^[ RightSide ];
+ Row16Bit^[ RightSide ] := Pixel;
+ dec( RightSide );
+ end;
+ inc( cardinal( Row16Bit ), DstSurface^.pitch );
+ end;
+ end;
+ 3 :
+ begin
+ Row24Bit := pointer( cardinal( DstSurface^.pixels ) + UInt32( Rect^.y ) *
+ DstSurface^.pitch );
+ for y := 1 to Rect^.h do
+ begin
+ RightSide := Rect^.w - 1;
+ for x := 0 to FlipLength do
+ begin
+ Pixel24 := Row24Bit^[ x ];
+ Row24Bit^[ x ] := Row24Bit^[ RightSide ];
+ Row24Bit^[ RightSide ] := Pixel24;
+ dec( RightSide );
+ end;
+ inc( cardinal( Row24Bit ), DstSurface^.pitch );
+ end;
+ end;
+ 4 :
+ begin
+ Row32Bit := pointer( cardinal( DstSurface^.pixels ) + UInt32( Rect^.y ) *
+ DstSurface^.pitch );
+ for y := 1 to Rect^.h do
+ begin
+ RightSide := Rect^.w - 1;
+ for x := 0 to FlipLength do
+ begin
+ Pixel := Row32Bit^[ x ];
+ Row32Bit^[ x ] := Row32Bit^[ RightSide ];
+ Row32Bit^[ RightSide ] := Pixel;
+ dec( RightSide );
+ end;
+ inc( cardinal( Row32Bit ), DstSurface^.pitch );
+ end;
+ end;
+ end;
+ if Locked then
+ SDL_UnlockSurface( DstSurface );
+ end;
+end;
+
+// Use with caution! The procedure allocates memory for TSDL_Rect and return with its pointer.
+// But you MUST free it after you don't need it anymore!!!
+
+function PSDLRect( aLeft, aTop, aWidth, aHeight : integer ) : PSDL_Rect;
+var
+ Rect : PSDL_Rect;
+begin
+ New( Rect );
+ with Rect^ do
+ begin
+ x := aLeft;
+ y := aTop;
+ w := aWidth;
+ h := aHeight;
+ end;
+ Result := Rect;
+end;
+
+function SDLRect( aLeft, aTop, aWidth, aHeight : integer ) : TSDL_Rect;
+begin
+ with result do
+ begin
+ x := aLeft;
+ y := aTop;
+ w := aWidth;
+ h := aHeight;
+ end;
+end;
+
+function SDLRect( aRect : TRect ) : TSDL_Rect;
+begin
+ with aRect do
+ result := SDLRect( Left, Top, Right - Left, Bottom - Top );
+end;
+
+procedure SDL_Stretch8( Surface, Dst_Surface : PSDL_Surface; x1, x2, y1, y2, yr, yw,
+ depth : integer );
+var
+ dx, dy, e, d, dx2 : integer;
+ src_pitch, dst_pitch : uint16;
+ src_pixels, dst_pixels : PUint8;
+begin
+ if ( yw >= dst_surface^.h ) then
+ exit;
+ dx := ( x2 - x1 );
+ dy := ( y2 - y1 );
+ dy := dy shl 1;
+ e := dy - dx;
+ dx2 := dx shl 1;
+ src_pitch := Surface^.pitch;
+ dst_pitch := dst_surface^.pitch;
+ src_pixels := PUint8( integer( Surface^.pixels ) + yr * src_pitch + y1 * depth );
+ dst_pixels := PUint8( integer( dst_surface^.pixels ) + yw * dst_pitch + x1 *
+ depth );
+ for d := 0 to dx - 1 do
+ begin
+ move( src_pixels^, dst_pixels^, depth );
+ while ( e >= 0 ) do
+ begin
+ inc( src_pixels, depth );
+ e := e - dx2;
+ end;
+ inc( dst_pixels, depth );
+ e := e + dy;
+ end;
+end;
+
+function sign( x : integer ) : integer;
+begin
+ if x > 0 then
+ result := 1
+ else
+ result := -1;
+end;
+
+// Stretches a part of a surface
+
+function SDL_ScaleSurfaceRect( SrcSurface : PSDL_Surface; SrcX1, SrcY1, SrcW, SrcH,
+ Width, Height : integer ) : PSDL_Surface;
+var
+ dst_surface : PSDL_Surface;
+ dx, dy, e, d, dx2, srcx2, srcy2 : integer;
+ destx1, desty1 : integer;
+begin
+ srcx2 := srcx1 + SrcW;
+ srcy2 := srcy1 + SrcH;
+ result := nil;
+ destx1 := 0;
+ desty1 := 0;
+ dx := abs( integer( Height - desty1 ) );
+ dy := abs( integer( SrcY2 - SrcY1 ) );
+ e := ( dy shl 1 ) - dx;
+ dx2 := dx shl 1;
+ dy := dy shl 1;
+ dst_surface := SDL_CreateRGBSurface( SDL_HWPALETTE, width - destx1, Height -
+ desty1,
+ SrcSurface^.Format^.BitsPerPixel,
+ SrcSurface^.Format^.RMask,
+ SrcSurface^.Format^.GMask,
+ SrcSurface^.Format^.BMask,
+ SrcSurface^.Format^.AMask );
+ if ( dst_surface^.format^.BytesPerPixel = 1 ) then
+ SDL_SetColors( dst_surface, @SrcSurface^.format^.palette^.colors^[ 0 ], 0, 256 );
+ SDL_SetColorKey( dst_surface, sdl_srccolorkey, SrcSurface^.format^.colorkey );
+ if ( SDL_MustLock( dst_surface ) ) then
+ if ( SDL_LockSurface( dst_surface ) < 0 ) then
+ exit;
+ for d := 0 to dx - 1 do
+ begin
+ SDL_Stretch8( SrcSurface, dst_surface, destx1, Width, SrcX1, SrcX2, SrcY1, desty1,
+ SrcSurface^.format^.BytesPerPixel );
+ while e >= 0 do
+ begin
+ inc( SrcY1 );
+ e := e - dx2;
+ end;
+ inc( desty1 );
+ e := e + dy;
+ end;
+ if SDL_MUSTLOCK( dst_surface ) then
+ SDL_UnlockSurface( dst_surface );
+ result := dst_surface;
+end;
+
+procedure SDL_MoveLine( Surface : PSDL_Surface; x1, x2, y1, xofs, depth : integer );
+var
+ src_pixels, dst_pixels : PUint8;
+ i : integer;
+begin
+ src_pixels := PUint8( integer( Surface^.pixels ) + Surface^.w * y1 * depth + x2 *
+ depth );
+ dst_pixels := PUint8( integer( Surface^.pixels ) + Surface^.w * y1 * depth + ( x2
+ + xofs ) * depth );
+ for i := x2 downto x1 do
+ begin
+ move( src_pixels^, dst_pixels^, depth );
+ dec( src_pixels );
+ dec( dst_pixels );
+ end;
+end;
+{ Return the pixel value at (x, y)
+NOTE: The surface must be locked before calling this! }
+
+function SDL_GetPixel( SrcSurface : PSDL_Surface; x : integer; y : integer ) : Uint32;
+var
+ bpp : UInt32;
+ p : PInteger;
+begin
+ bpp := SrcSurface.format.BytesPerPixel;
+ // Here p is the address to the pixel we want to retrieve
+ p := Pointer( Uint32( SrcSurface.pixels ) + UInt32( y ) * SrcSurface.pitch + UInt32( x ) *
+ bpp );
+ case bpp of
+ 1 : result := PUint8( p )^;
+ 2 : result := PUint16( p )^;
+ 3 :
+ if ( SDL_BYTEORDER = SDL_BIG_ENDIAN ) then
+ result := PUInt8Array( p )[ 0 ] shl 16 or PUInt8Array( p )[ 1 ] shl 8 or
+ PUInt8Array( p )[ 2 ]
+ else
+ result := PUInt8Array( p )[ 0 ] or PUInt8Array( p )[ 1 ] shl 8 or
+ PUInt8Array( p )[ 2 ] shl 16;
+ 4 : result := PUint32( p )^;
+ else
+ result := 0; // shouldn't happen, but avoids warnings
+ end;
+end;
+{ Set the pixel at (x, y) to the given value
+ NOTE: The surface must be locked before calling this! }
+
+procedure SDL_PutPixel( DstSurface : PSDL_Surface; x : integer; y : integer; pixel :
+ Uint32 );
+var
+ bpp : UInt32;
+ p : PInteger;
+begin
+ bpp := DstSurface.format.BytesPerPixel;
+ p := Pointer( Uint32( DstSurface.pixels ) + UInt32( y ) * DstSurface.pitch + UInt32( x )
+ * bpp );
+ case bpp of
+ 1 : PUint8( p )^ := pixel;
+ 2 : PUint16( p )^ := pixel;
+ 3 :
+ if ( SDL_BYTEORDER = SDL_BIG_ENDIAN ) then
+ begin
+ PUInt8Array( p )[ 0 ] := ( pixel shr 16 ) and $FF;
+ PUInt8Array( p )[ 1 ] := ( pixel shr 8 ) and $FF;
+ PUInt8Array( p )[ 2 ] := pixel and $FF;
+ end
+ else
+ begin
+ PUInt8Array( p )[ 0 ] := pixel and $FF;
+ PUInt8Array( p )[ 1 ] := ( pixel shr 8 ) and $FF;
+ PUInt8Array( p )[ 2 ] := ( pixel shr 16 ) and $FF;
+ end;
+ 4 :
+ PUint32( p )^ := pixel;
+ end;
+end;
+
+procedure SDL_ScrollY( DstSurface : PSDL_Surface; DifY : integer );
+var
+ r1, r2 : TSDL_Rect;
+ //buffer: PSDL_Surface;
+ YPos : Integer;
+begin
+ if ( DstSurface <> nil ) and ( DifY <> 0 ) then
+ begin
+ //if DifY > 0 then // going up
+ //begin
+ ypos := 0;
+ r1.x := 0;
+ r2.x := 0;
+ r1.w := DstSurface.w;
+ r2.w := DstSurface.w;
+ r1.h := DifY;
+ r2.h := DifY;
+ while ypos < DstSurface.h do
+ begin
+ r1.y := ypos;
+ r2.y := ypos + DifY;
+ SDL_BlitSurface( DstSurface, @r2, DstSurface, @r1 );
+ ypos := ypos + DifY;
+ end;
+ //end
+ //else
+ //begin // Going Down
+ //end;
+ end;
+end;
+
+{procedure SDL_ScrollY(Surface: PSDL_Surface; DifY: integer);
+var
+ r1, r2: TSDL_Rect;
+ buffer: PSDL_Surface;
+begin
+ if (Surface <> nil) and (Dify <> 0) then
+ begin
+ buffer := SDL_CreateRGBSurface(SDL_HWSURFACE, (Surface^.w - DifY) * 2,
+ Surface^.h * 2,
+ Surface^.Format^.BitsPerPixel, 0, 0, 0, 0);
+ if buffer <> nil then
+ begin
+ if (buffer^.format^.BytesPerPixel = 1) then
+ SDL_SetColors(buffer, @Surface^.format^.palette^.colors^[0], 0, 256);
+ r1 := SDLRect(0, DifY, buffer^.w, buffer^.h);
+ r2 := SDLRect(0, 0, buffer^.w, buffer^.h);
+ SDL_BlitSurface(Surface, @r1, buffer, @r2);
+ SDL_BlitSurface(buffer, @r2, Surface, @r2);
+ SDL_FreeSurface(buffer);
+ end;
+ end;
+end;}
+
+procedure SDL_ScrollX( DstSurface : PSDL_Surface; DifX : integer );
+var
+ r1, r2 : TSDL_Rect;
+ buffer : PSDL_Surface;
+begin
+ if ( DstSurface <> nil ) and ( DifX <> 0 ) then
+ begin
+ buffer := SDL_CreateRGBSurface( SDL_HWSURFACE, ( DstSurface^.w - DifX ) * 2,
+ DstSurface^.h * 2,
+ DstSurface^.Format^.BitsPerPixel,
+ DstSurface^.Format^.RMask,
+ DstSurface^.Format^.GMask,
+ DstSurface^.Format^.BMask,
+ DstSurface^.Format^.AMask );
+ if buffer <> nil then
+ begin
+ if ( buffer^.format^.BytesPerPixel = 1 ) then
+ SDL_SetColors( buffer, @DstSurface^.format^.palette^.colors^[ 0 ], 0, 256 );
+ r1 := SDLRect( DifX, 0, buffer^.w, buffer^.h );
+ r2 := SDLRect( 0, 0, buffer^.w, buffer^.h );
+ SDL_BlitSurface( DstSurface, @r1, buffer, @r2 );
+ SDL_BlitSurface( buffer, @r2, DstSurface, @r2 );
+ SDL_FreeSurface( buffer );
+ end;
+ end;
+end;
+
+procedure SDL_RotateRad( DstSurface, SrcSurface : PSDL_Surface; SrcRect :
+ PSDL_Rect; DestX, DestY, OffsetX, OffsetY : Integer; Angle : Single );
+var
+ aSin, aCos : Single;
+ MX, MY, DX, DY, NX, NY, SX, SY, OX, OY, Width, Height, TX, TY, RX, RY, ROX, ROY : Integer;
+ Colour, TempTransparentColour : UInt32;
+ MAXX, MAXY : Integer;
+begin
+ // Rotate the surface to the target surface.
+ TempTransparentColour := SrcSurface.format.colorkey;
+ {if srcRect.w > srcRect.h then
+ begin
+ Width := srcRect.w;
+ Height := srcRect.w;
+ end
+ else
+ begin
+ Width := srcRect.h;
+ Height := srcRect.h;
+ end; }
+
+ maxx := DstSurface.w;
+ maxy := DstSurface.h;
+ aCos := cos( Angle );
+ aSin := sin( Angle );
+
+ Width := round( abs( srcrect.h * acos ) + abs( srcrect.w * asin ) );
+ Height := round( abs( srcrect.h * asin ) + abs( srcrect.w * acos ) );
+
+ OX := Width div 2;
+ OY := Height div 2; ;
+ MX := ( srcRect.x + ( srcRect.x + srcRect.w ) ) div 2;
+ MY := ( srcRect.y + ( srcRect.y + srcRect.h ) ) div 2;
+ ROX := ( -( srcRect.w div 2 ) ) + Offsetx;
+ ROY := ( -( srcRect.h div 2 ) ) + OffsetY;
+ Tx := ox + round( ROX * aSin - ROY * aCos );
+ Ty := oy + round( ROY * aSin + ROX * aCos );
+ SX := 0;
+ for DX := DestX - TX to DestX - TX + ( width ) do
+ begin
+ Inc( SX );
+ SY := 0;
+ for DY := DestY - TY to DestY - TY + ( Height ) do
+ begin
+ RX := SX - OX;
+ RY := SY - OY;
+ NX := round( mx + RX * aSin + RY * aCos ); //
+ NY := round( my + RY * aSin - RX * aCos ); //
+ // Used for testing only
+ //SDL_PutPixel(DestSurface.SDLSurfacePointer,DX,DY,0);
+ if ( ( DX > 0 ) and ( DX < MAXX ) ) and ( ( DY > 0 ) and ( DY < MAXY ) ) then
+ begin
+ if ( NX >= srcRect.x ) and ( NX <= srcRect.x + srcRect.w ) then
+ begin
+ if ( NY >= srcRect.y ) and ( NY <= srcRect.y + srcRect.h ) then
+ begin
+ Colour := SDL_GetPixel( SrcSurface, NX, NY );
+ if Colour <> TempTransparentColour then
+ begin
+ SDL_PutPixel( DstSurface, DX, DY, Colour );
+ end;
+ end;
+ end;
+ end;
+ inc( SY );
+ end;
+ end;
+end;
+
+procedure SDL_RotateDeg( DstSurface, SrcSurface : PSDL_Surface; SrcRect :
+ PSDL_Rect; DestX, DestY, OffsetX, OffsetY : Integer; Angle : Integer );
+begin
+ SDL_RotateRad( DstSurface, SrcSurface, SrcRect, DestX, DestY, OffsetX, OffsetY, DegToRad( Angle ) );
+end;
+
+function ValidateSurfaceRect( DstSurface : PSDL_Surface; dstrect : PSDL_Rect ) : TSDL_Rect;
+var
+ RealRect : TSDL_Rect;
+ OutOfRange : Boolean;
+begin
+ OutOfRange := false;
+ if dstrect = nil then
+ begin
+ RealRect.x := 0;
+ RealRect.y := 0;
+ RealRect.w := DstSurface.w;
+ RealRect.h := DstSurface.h;
+ end
+ else
+ begin
+ if dstrect.x < DstSurface.w then
+ begin
+ RealRect.x := dstrect.x;
+ end
+ else if dstrect.x < 0 then
+ begin
+ realrect.x := 0;
+ end
+ else
+ begin
+ OutOfRange := True;
+ end;
+ if dstrect.y < DstSurface.h then
+ begin
+ RealRect.y := dstrect.y;
+ end
+ else if dstrect.y < 0 then
+ begin
+ realrect.y := 0;
+ end
+ else
+ begin
+ OutOfRange := True;
+ end;
+ if OutOfRange = False then
+ begin
+ if realrect.x + dstrect.w <= DstSurface.w then
+ begin
+ RealRect.w := dstrect.w;
+ end
+ else
+ begin
+ RealRect.w := dstrect.w - realrect.x;
+ end;
+ if realrect.y + dstrect.h <= DstSurface.h then
+ begin
+ RealRect.h := dstrect.h;
+ end
+ else
+ begin
+ RealRect.h := dstrect.h - realrect.y;
+ end;
+ end;
+ end;
+ if OutOfRange = False then
+ begin
+ result := realrect;
+ end
+ else
+ begin
+ realrect.w := 0;
+ realrect.h := 0;
+ realrect.x := 0;
+ realrect.y := 0;
+ result := realrect;
+ end;
+end;
+
+procedure SDL_FillRectAdd( DstSurface : PSDL_Surface; dstrect : PSDL_Rect; color : UInt32 );
+var
+ RealRect : TSDL_Rect;
+ Addr : pointer;
+ ModX, BPP : cardinal;
+ x, y, R, G, B, SrcColor : cardinal;
+begin
+ RealRect := ValidateSurfaceRect( DstSurface, DstRect );
+ if ( RealRect.w > 0 ) and ( RealRect.h > 0 ) then
+ begin
+ SDL_LockSurface( DstSurface );
+ BPP := DstSurface.format.BytesPerPixel;
+ with DstSurface^ do
+ begin
+ Addr := pointer( UInt32( pixels ) + UInt32( RealRect.y ) * pitch + UInt32( RealRect.x ) * BPP );
+ ModX := Pitch - UInt32( RealRect.w ) * BPP;
+ end;
+ case DstSurface.format.BitsPerPixel of
+ 8 :
+ begin
+ for y := 0 to RealRect.h - 1 do
+ begin
+ for x := 0 to RealRect.w - 1 do
+ begin
+ SrcColor := PUInt32( Addr )^;
+ R := SrcColor and $E0 + Color and $E0;
+ G := SrcColor and $1C + Color and $1C;
+ B := SrcColor and $03 + Color and $03;
+ if R > $E0 then
+ R := $E0;
+ if G > $1C then
+ G := $1C;
+ if B > $03 then
+ B := $03;
+ PUInt8( Addr )^ := R or G or B;
+ inc( UInt32( Addr ), BPP );
+ end;
+ inc( UInt32( Addr ), ModX );
+ end;
+ end;
+ 15 :
+ begin
+ for y := 0 to RealRect.h - 1 do
+ begin
+ for x := 0 to RealRect.w - 1 do
+ begin
+ SrcColor := PUInt32( Addr )^;
+ R := SrcColor and $7C00 + Color and $7C00;
+ G := SrcColor and $03E0 + Color and $03E0;
+ B := SrcColor and $001F + Color and $001F;
+ if R > $7C00 then
+ R := $7C00;
+ if G > $03E0 then
+ G := $03E0;
+ if B > $001F then
+ B := $001F;
+ PUInt16( Addr )^ := R or G or B;
+ inc( UInt32( Addr ), BPP );
+ end;
+ inc( UInt32( Addr ), ModX );
+ end;
+ end;
+ 16 :
+ begin
+ for y := 0 to RealRect.h - 1 do
+ begin
+ for x := 0 to RealRect.w - 1 do
+ begin
+ SrcColor := PUInt32( Addr )^;
+ R := SrcColor and $F800 + Color and $F800;
+ G := SrcColor and $07C0 + Color and $07C0;
+ B := SrcColor and $001F + Color and $001F;
+ if R > $F800 then
+ R := $F800;
+ if G > $07C0 then
+ G := $07C0;
+ if B > $001F then
+ B := $001F;
+ PUInt16( Addr )^ := R or G or B;
+ inc( UInt32( Addr ), BPP );
+ end;
+ inc( UInt32( Addr ), ModX );
+ end;
+ end;
+ 24 :
+ begin
+ for y := 0 to RealRect.h - 1 do
+ begin
+ for x := 0 to RealRect.w - 1 do
+ begin
+ SrcColor := PUInt32( Addr )^;
+ R := SrcColor and $00FF0000 + Color and $00FF0000;
+ G := SrcColor and $0000FF00 + Color and $0000FF00;
+ B := SrcColor and $000000FF + Color and $000000FF;
+ if R > $FF0000 then
+ R := $FF0000;
+ if G > $00FF00 then
+ G := $00FF00;
+ if B > $0000FF then
+ B := $0000FF;
+ PUInt32( Addr )^ := SrcColor and $FF000000 or R or G or B;
+ inc( UInt32( Addr ), BPP );
+ end;
+ inc( UInt32( Addr ), ModX );
+ end;
+ end;
+ 32 :
+ begin
+ for y := 0 to RealRect.h - 1 do
+ begin
+ for x := 0 to RealRect.w - 1 do
+ begin
+ SrcColor := PUInt32( Addr )^;
+ R := SrcColor and $00FF0000 + Color and $00FF0000;
+ G := SrcColor and $0000FF00 + Color and $0000FF00;
+ B := SrcColor and $000000FF + Color and $000000FF;
+ if R > $FF0000 then
+ R := $FF0000;
+ if G > $00FF00 then
+ G := $00FF00;
+ if B > $0000FF then
+ B := $0000FF;
+ PUInt32( Addr )^ := R or G or B;
+ inc( UInt32( Addr ), BPP );
+ end;
+ inc( UInt32( Addr ), ModX );
+ end;
+ end;
+ end;
+ SDL_UnlockSurface( DstSurface );
+ end;
+end;
+
+procedure SDL_FillRectSub( DstSurface : PSDL_Surface; dstrect : PSDL_Rect; color : UInt32 );
+var
+ RealRect : TSDL_Rect;
+ Addr : pointer;
+ ModX, BPP : cardinal;
+ x, y, R, G, B, SrcColor : cardinal;
+begin
+ RealRect := ValidateSurfaceRect( DstSurface, DstRect );
+ if ( RealRect.w > 0 ) and ( RealRect.h > 0 ) then
+ begin
+ SDL_LockSurface( DstSurface );
+ BPP := DstSurface.format.BytesPerPixel;
+ with DstSurface^ do
+ begin
+ Addr := pointer( UInt32( pixels ) + UInt32( RealRect.y ) * pitch + UInt32( RealRect.x ) * BPP );
+ ModX := Pitch - UInt32( RealRect.w ) * BPP;
+ end;
+ case DstSurface.format.BitsPerPixel of
+ 8 :
+ begin
+ for y := 0 to RealRect.h - 1 do
+ begin
+ for x := 0 to RealRect.w - 1 do
+ begin
+ SrcColor := PUInt32( Addr )^;
+ R := SrcColor and $E0 - Color and $E0;
+ G := SrcColor and $1C - Color and $1C;
+ B := SrcColor and $03 - Color and $03;
+ if R > $E0 then
+ R := 0;
+ if G > $1C then
+ G := 0;
+ if B > $03 then
+ B := 0;
+ PUInt8( Addr )^ := R or G or B;
+ inc( UInt32( Addr ), BPP );
+ end;
+ inc( UInt32( Addr ), ModX );
+ end;
+ end;
+ 15 :
+ begin
+ for y := 0 to RealRect.h - 1 do
+ begin
+ for x := 0 to RealRect.w - 1 do
+ begin
+ SrcColor := PUInt32( Addr )^;
+ R := SrcColor and $7C00 - Color and $7C00;
+ G := SrcColor and $03E0 - Color and $03E0;
+ B := SrcColor and $001F - Color and $001F;
+ if R > $7C00 then
+ R := 0;
+ if G > $03E0 then
+ G := 0;
+ if B > $001F then
+ B := 0;
+ PUInt16( Addr )^ := R or G or B;
+ inc( UInt32( Addr ), BPP );
+ end;
+ inc( UInt32( Addr ), ModX );
+ end;
+ end;
+ 16 :
+ begin
+ for y := 0 to RealRect.h - 1 do
+ begin
+ for x := 0 to RealRect.w - 1 do
+ begin
+ SrcColor := PUInt32( Addr )^;
+ R := SrcColor and $F800 - Color and $F800;
+ G := SrcColor and $07C0 - Color and $07C0;
+ B := SrcColor and $001F - Color and $001F;
+ if R > $F800 then
+ R := 0;
+ if G > $07C0 then
+ G := 0;
+ if B > $001F then
+ B := 0;
+ PUInt16( Addr )^ := R or G or B;
+ inc( UInt32( Addr ), BPP );
+ end;
+ inc( UInt32( Addr ), ModX );
+ end;
+ end;
+ 24 :
+ begin
+ for y := 0 to RealRect.h - 1 do
+ begin
+ for x := 0 to RealRect.w - 1 do
+ begin
+ SrcColor := PUInt32( Addr )^;
+ R := SrcColor and $00FF0000 - Color and $00FF0000;
+ G := SrcColor and $0000FF00 - Color and $0000FF00;
+ B := SrcColor and $000000FF - Color and $000000FF;
+ if R > $FF0000 then
+ R := 0;
+ if G > $00FF00 then
+ G := 0;
+ if B > $0000FF then
+ B := 0;
+ PUInt32( Addr )^ := SrcColor and $FF000000 or R or G or B;
+ inc( UInt32( Addr ), BPP );
+ end;
+ inc( UInt32( Addr ), ModX );
+ end;
+ end;
+ 32 :
+ begin
+ for y := 0 to RealRect.h - 1 do
+ begin
+ for x := 0 to RealRect.w - 1 do
+ begin
+ SrcColor := PUInt32( Addr )^;
+ R := SrcColor and $00FF0000 - Color and $00FF0000;
+ G := SrcColor and $0000FF00 - Color and $0000FF00;
+ B := SrcColor and $000000FF - Color and $000000FF;
+ if R > $FF0000 then
+ R := 0;
+ if G > $00FF00 then
+ G := 0;
+ if B > $0000FF then
+ B := 0;
+ PUInt32( Addr )^ := R or G or B;
+ inc( UInt32( Addr ), BPP );
+ end;
+ inc( UInt32( Addr ), ModX );
+ end;
+ end;
+ end;
+ SDL_UnlockSurface( DstSurface );
+ end;
+end;
+
+procedure SDL_GradientFillRect( DstSurface : PSDL_Surface; const Rect : PSDL_Rect; const StartColor, EndColor : TSDL_Color; const Style : TGradientStyle );
+var
+ FBC : array[ 0..255 ] of Cardinal;
+ // temp vars
+ i, YR, YG, YB, SR, SG, SB, DR, DG, DB : Integer;
+
+ TempStepV, TempStepH : Single;
+ TempLeft, TempTop, TempHeight, TempWidth : integer;
+ TempRect : TSDL_Rect;
+
+begin
+ // calc FBC
+ YR := StartColor.r;
+ YG := StartColor.g;
+ YB := StartColor.b;
+ SR := YR;
+ SG := YG;
+ SB := YB;
+ DR := EndColor.r - SR;
+ DG := EndColor.g - SG;
+ DB := EndColor.b - SB;
+
+ for i := 0 to 255 do
+ begin
+ FBC[ i ] := SDL_MapRGB( DstSurface.format, YR, YG, YB );
+ YR := SR + round( DR / 255 * i );
+ YG := SG + round( DG / 255 * i );
+ YB := SB + round( DB / 255 * i );
+ end;
+
+ // if aStyle = 1 then begin
+ TempStepH := Rect.w / 255;
+ TempStepV := Rect.h / 255;
+ TempHeight := Trunc( TempStepV + 1 );
+ TempWidth := Trunc( TempStepH + 1 );
+ TempTop := 0;
+ TempLeft := 0;
+ TempRect.x := Rect.x;
+ TempRect.y := Rect.y;
+ TempRect.h := Rect.h;
+ TempRect.w := Rect.w;
+
+ case Style of
+ gsHorizontal :
+ begin
+ TempRect.h := TempHeight;
+ for i := 0 to 255 do
+ begin
+ TempRect.y := Rect.y + TempTop;
+ SDL_FillRect( DstSurface, @TempRect, FBC[ i ] );
+ TempTop := Trunc( TempStepV * i );
+ end;
+ end;
+ gsVertical :
+ begin
+ TempRect.w := TempWidth;
+ for i := 0 to 255 do
+ begin
+ TempRect.x := Rect.x + TempLeft;
+ SDL_FillRect( DstSurface, @TempRect, FBC[ i ] );
+ TempLeft := Trunc( TempStepH * i );
+ end;
+ end;
+ end;
+end;
+
+procedure SDL_2xBlit( Src, Dest : PSDL_Surface );
+var
+ ReadAddr, WriteAddr, ReadRow, WriteRow : UInt32;
+ SrcPitch, DestPitch, x, y : UInt32;
+begin
+ if ( Src = nil ) or ( Dest = nil ) then
+ exit;
+ if ( Src.w shl 1 ) < Dest.w then
+ exit;
+ if ( Src.h shl 1 ) < Dest.h then
+ exit;
+
+ if SDL_MustLock( Src ) then
+ SDL_LockSurface( Src );
+ if SDL_MustLock( Dest ) then
+ SDL_LockSurface( Dest );
+
+ ReadRow := UInt32( Src.Pixels );
+ WriteRow := UInt32( Dest.Pixels );
+
+ SrcPitch := Src.pitch;
+ DestPitch := Dest.pitch;
+
+ case Src.format.BytesPerPixel of
+ 1 : for y := 1 to Src.h do
+ begin
+ ReadAddr := ReadRow;
+ WriteAddr := WriteRow;
+ for x := 1 to Src.w do
+ begin
+ PUInt8( WriteAddr )^ := PUInt8( ReadAddr )^;
+ PUInt8( WriteAddr + 1 )^ := PUInt8( ReadAddr )^;
+ PUInt8( WriteAddr + DestPitch )^ := PUInt8( ReadAddr )^;
+ PUInt8( WriteAddr + DestPitch + 1 )^ := PUInt8( ReadAddr )^;
+ inc( ReadAddr );
+ inc( WriteAddr, 2 );
+ end;
+ inc( UInt32( ReadRow ), SrcPitch );
+ inc( UInt32( WriteRow ), DestPitch * 2 );
+ end;
+ 2 : for y := 1 to Src.h do
+ begin
+ ReadAddr := ReadRow;
+ WriteAddr := WriteRow;
+ for x := 1 to Src.w do
+ begin
+ PUInt16( WriteAddr )^ := PUInt16( ReadAddr )^;
+ PUInt16( WriteAddr + 2 )^ := PUInt16( ReadAddr )^;
+ PUInt16( WriteAddr + DestPitch )^ := PUInt16( ReadAddr )^;
+ PUInt16( WriteAddr + DestPitch + 2 )^ := PUInt16( ReadAddr )^;
+ inc( ReadAddr, 2 );
+ inc( WriteAddr, 4 );
+ end;
+ inc( UInt32( ReadRow ), SrcPitch );
+ inc( UInt32( WriteRow ), DestPitch * 2 );
+ end;
+ 3 : for y := 1 to Src.h do
+ begin
+ ReadAddr := ReadRow;
+ WriteAddr := WriteRow;
+ for x := 1 to Src.w do
+ begin
+ PUInt32( WriteAddr )^ := ( PUInt32( WriteAddr )^ and $FF000000 ) or ( PUInt32( ReadAddr )^ and $00FFFFFF );
+ PUInt32( WriteAddr + 3 )^ := ( PUInt32( WriteAddr + 3 )^ and $FF000000 ) or ( PUInt32( ReadAddr )^ and $00FFFFFF );
+ PUInt32( WriteAddr + DestPitch )^ := ( PUInt32( WriteAddr + DestPitch )^ and $FF000000 ) or ( PUInt32( ReadAddr )^ and $00FFFFFF );
+ PUInt32( WriteAddr + DestPitch + 3 )^ := ( PUInt32( WriteAddr + DestPitch + 3 )^ and $FF000000 ) or ( PUInt32( ReadAddr )^ and $00FFFFFF );
+ inc( ReadAddr, 3 );
+ inc( WriteAddr, 6 );
+ end;
+ inc( UInt32( ReadRow ), SrcPitch );
+ inc( UInt32( WriteRow ), DestPitch * 2 );
+ end;
+ 4 : for y := 1 to Src.h do
+ begin
+ ReadAddr := ReadRow;
+ WriteAddr := WriteRow;
+ for x := 1 to Src.w do
+ begin
+ PUInt32( WriteAddr )^ := PUInt32( ReadAddr )^;
+ PUInt32( WriteAddr + 4 )^ := PUInt32( ReadAddr )^;
+ PUInt32( WriteAddr + DestPitch )^ := PUInt32( ReadAddr )^;
+ PUInt32( WriteAddr + DestPitch + 4 )^ := PUInt32( ReadAddr )^;
+ inc( ReadAddr, 4 );
+ inc( WriteAddr, 8 );
+ end;
+ inc( UInt32( ReadRow ), SrcPitch );
+ inc( UInt32( WriteRow ), DestPitch * 2 );
+ end;
+ end;
+
+ if SDL_MustLock( Src ) then
+ SDL_UnlockSurface( Src );
+ if SDL_MustLock( Dest ) then
+ SDL_UnlockSurface( Dest );
+end;
+
+procedure SDL_Scanline2xBlit( Src, Dest : PSDL_Surface );
+var
+ ReadAddr, WriteAddr, ReadRow, WriteRow : UInt32;
+ SrcPitch, DestPitch, x, y : UInt32;
+begin
+ if ( Src = nil ) or ( Dest = nil ) then
+ exit;
+ if ( Src.w shl 1 ) < Dest.w then
+ exit;
+ if ( Src.h shl 1 ) < Dest.h then
+ exit;
+
+ if SDL_MustLock( Src ) then
+ SDL_LockSurface( Src );
+ if SDL_MustLock( Dest ) then
+ SDL_LockSurface( Dest );
+
+ ReadRow := UInt32( Src.Pixels );
+ WriteRow := UInt32( Dest.Pixels );
+
+ SrcPitch := Src.pitch;
+ DestPitch := Dest.pitch;
+
+ case Src.format.BytesPerPixel of
+ 1 : for y := 1 to Src.h do
+ begin
+ ReadAddr := ReadRow;
+ WriteAddr := WriteRow;
+ for x := 1 to Src.w do
+ begin
+ PUInt8( WriteAddr )^ := PUInt8( ReadAddr )^;
+ PUInt8( WriteAddr + 1 )^ := PUInt8( ReadAddr )^;
+ inc( ReadAddr );
+ inc( WriteAddr, 2 );
+ end;
+ inc( UInt32( ReadRow ), SrcPitch );
+ inc( UInt32( WriteRow ), DestPitch * 2 );
+ end;
+ 2 : for y := 1 to Src.h do
+ begin
+ ReadAddr := ReadRow;
+ WriteAddr := WriteRow;
+ for x := 1 to Src.w do
+ begin
+ PUInt16( WriteAddr )^ := PUInt16( ReadAddr )^;
+ PUInt16( WriteAddr + 2 )^ := PUInt16( ReadAddr )^;
+ inc( ReadAddr, 2 );
+ inc( WriteAddr, 4 );
+ end;
+ inc( UInt32( ReadRow ), SrcPitch );
+ inc( UInt32( WriteRow ), DestPitch * 2 );
+ end;
+ 3 : for y := 1 to Src.h do
+ begin
+ ReadAddr := ReadRow;
+ WriteAddr := WriteRow;
+ for x := 1 to Src.w do
+ begin
+ PUInt32( WriteAddr )^ := ( PUInt32( WriteAddr )^ and $FF000000 ) or ( PUInt32( ReadAddr )^ and $00FFFFFF );
+ PUInt32( WriteAddr + 3 )^ := ( PUInt32( WriteAddr + 3 )^ and $FF000000 ) or ( PUInt32( ReadAddr )^ and $00FFFFFF );
+ inc( ReadAddr, 3 );
+ inc( WriteAddr, 6 );
+ end;
+ inc( UInt32( ReadRow ), SrcPitch );
+ inc( UInt32( WriteRow ), DestPitch * 2 );
+ end;
+ 4 : for y := 1 to Src.h do
+ begin
+ ReadAddr := ReadRow;
+ WriteAddr := WriteRow;
+ for x := 1 to Src.w do
+ begin
+ PUInt32( WriteAddr )^ := PUInt32( ReadAddr )^;
+ PUInt32( WriteAddr + 4 )^ := PUInt32( ReadAddr )^;
+ inc( ReadAddr, 4 );
+ inc( WriteAddr, 8 );
+ end;
+ inc( UInt32( ReadRow ), SrcPitch );
+ inc( UInt32( WriteRow ), DestPitch * 2 );
+ end;
+ end;
+
+ if SDL_MustLock( Src ) then
+ SDL_UnlockSurface( Src );
+ if SDL_MustLock( Dest ) then
+ SDL_UnlockSurface( Dest );
+end;
+
+procedure SDL_50Scanline2xBlit( Src, Dest : PSDL_Surface );
+var
+ ReadAddr, WriteAddr, ReadRow, WriteRow : UInt32;
+ SrcPitch, DestPitch, x, y, Color : UInt32;
+begin
+ if ( Src = nil ) or ( Dest = nil ) then
+ exit;
+ if ( Src.w shl 1 ) < Dest.w then
+ exit;
+ if ( Src.h shl 1 ) < Dest.h then
+ exit;
+
+ if SDL_MustLock( Src ) then
+ SDL_LockSurface( Src );
+ if SDL_MustLock( Dest ) then
+ SDL_LockSurface( Dest );
+
+ ReadRow := UInt32( Src.Pixels );
+ WriteRow := UInt32( Dest.Pixels );
+
+ SrcPitch := Src.pitch;
+ DestPitch := Dest.pitch;
+
+ case Src.format.BitsPerPixel of
+ 8 : for y := 1 to Src.h do
+ begin
+ ReadAddr := ReadRow;
+ WriteAddr := WriteRow;
+ for x := 1 to Src.w do
+ begin
+ Color := PUInt8( ReadAddr )^;
+ PUInt8( WriteAddr )^ := Color;
+ PUInt8( WriteAddr + 1 )^ := Color;
+ Color := ( Color shr 1 ) and $6D; {%01101101}
+ PUInt8( WriteAddr + DestPitch )^ := Color;
+ PUInt8( WriteAddr + DestPitch + 1 )^ := Color;
+ inc( ReadAddr );
+ inc( WriteAddr, 2 );
+ end;
+ inc( UInt32( ReadRow ), SrcPitch );
+ inc( UInt32( WriteRow ), DestPitch * 2 );
+ end;
+ 15 : for y := 1 to Src.h do
+ begin
+ ReadAddr := ReadRow;
+ WriteAddr := WriteRow;
+ for x := 1 to Src.w do
+ begin
+ Color := PUInt16( ReadAddr )^;
+ PUInt16( WriteAddr )^ := Color;
+ PUInt16( WriteAddr + 2 )^ := Color;
+ Color := ( Color shr 1 ) and $3DEF; {%0011110111101111}
+ PUInt16( WriteAddr + DestPitch )^ := Color;
+ PUInt16( WriteAddr + DestPitch + 2 )^ := Color;
+ inc( ReadAddr, 2 );
+ inc( WriteAddr, 4 );
+ end;
+ inc( UInt32( ReadRow ), SrcPitch );
+ inc( UInt32( WriteRow ), DestPitch * 2 );
+ end;
+ 16 : for y := 1 to Src.h do
+ begin
+ ReadAddr := ReadRow;
+ WriteAddr := WriteRow;
+ for x := 1 to Src.w do
+ begin
+ Color := PUInt16( ReadAddr )^;
+ PUInt16( WriteAddr )^ := Color;
+ PUInt16( WriteAddr + 2 )^ := Color;
+ Color := ( Color shr 1 ) and $7BEF; {%0111101111101111}
+ PUInt16( WriteAddr + DestPitch )^ := Color;
+ PUInt16( WriteAddr + DestPitch + 2 )^ := Color;
+ inc( ReadAddr, 2 );
+ inc( WriteAddr, 4 );
+ end;
+ inc( UInt32( ReadRow ), SrcPitch );
+ inc( UInt32( WriteRow ), DestPitch * 2 );
+ end;
+ 24 : for y := 1 to Src.h do
+ begin
+ ReadAddr := ReadRow;
+ WriteAddr := WriteRow;
+ for x := 1 to Src.w do
+ begin
+ Color := ( PUInt32( WriteAddr )^ and $FF000000 ) or ( PUInt32( ReadAddr )^ and $00FFFFFF );
+ PUInt32( WriteAddr )^ := Color;
+ PUInt32( WriteAddr + 3 )^ := Color;
+ Color := ( Color shr 1 ) and $007F7F7F; {%011111110111111101111111}
+ PUInt32( WriteAddr + DestPitch )^ := Color;
+ PUInt32( WriteAddr + DestPitch + 3 )^ := Color;
+ inc( ReadAddr, 3 );
+ inc( WriteAddr, 6 );
+ end;
+ inc( UInt32( ReadRow ), SrcPitch );
+ inc( UInt32( WriteRow ), DestPitch * 2 );
+ end;
+ 32 : for y := 1 to Src.h do
+ begin
+ ReadAddr := ReadRow;
+ WriteAddr := WriteRow;
+ for x := 1 to Src.w do
+ begin
+ Color := PUInt32( ReadAddr )^;
+ PUInt32( WriteAddr )^ := Color;
+ PUInt32( WriteAddr + 4 )^ := Color;
+ Color := ( Color shr 1 ) and $7F7F7F7F;
+ PUInt32( WriteAddr + DestPitch )^ := Color;
+ PUInt32( WriteAddr + DestPitch + 4 )^ := Color;
+ inc( ReadAddr, 4 );
+ inc( WriteAddr, 8 );
+ end;
+ inc( UInt32( ReadRow ), SrcPitch );
+ inc( UInt32( WriteRow ), DestPitch * 2 );
+ end;
+ end;
+
+ if SDL_MustLock( Src ) then
+ SDL_UnlockSurface( Src );
+ if SDL_MustLock( Dest ) then
+ SDL_UnlockSurface( Dest );
+end;
+
+function SDL_PixelTestSurfaceVsRect( SrcSurface1 : PSDL_Surface; SrcRect1 :
+ PSDL_Rect; SrcRect2 : PSDL_Rect; Left1, Top1, Left2, Top2 : integer ) :
+ boolean;
+var
+ Src_Rect1, Src_Rect2 : TSDL_Rect;
+ right1, bottom1 : integer;
+ right2, bottom2 : integer;
+ Scan1Start, {Scan2Start,} ScanWidth, ScanHeight : cardinal;
+ Mod1 : cardinal;
+ Addr1 : cardinal;
+ BPP : cardinal;
+ Pitch1 : cardinal;
+ TransparentColor1 : cardinal;
+ tx, ty : cardinal;
+ StartTick : cardinal;
+ Color1 : cardinal;
+begin
+ Result := false;
+ if SrcRect1 = nil then
+ begin
+ with Src_Rect1 do
+ begin
+ x := 0;
+ y := 0;
+ w := SrcSurface1.w;
+ h := SrcSurface1.h;
+ end;
+ end
+ else
+ Src_Rect1 := SrcRect1^;
+
+ Src_Rect2 := SrcRect2^;
+ with Src_Rect1 do
+ begin
+ Right1 := Left1 + w;
+ Bottom1 := Top1 + h;
+ end;
+ with Src_Rect2 do
+ begin
+ Right2 := Left2 + w;
+ Bottom2 := Top2 + h;
+ end;
+ if ( Left1 >= Right2 ) or ( Right1 <= Left2 ) or ( Top1 >= Bottom2 ) or ( Bottom1 <= Top2 ) then
+ exit;
+ if Left1 <= Left2 then
+ begin
+ // 1. left, 2. right
+ Scan1Start := Src_Rect1.x + Left2 - Left1;
+ //Scan2Start := Src_Rect2.x;
+ ScanWidth := Right1 - Left2;
+ with Src_Rect2 do
+ if ScanWidth > w then
+ ScanWidth := w;
+ end
+ else
+ begin
+ // 1. right, 2. left
+ Scan1Start := Src_Rect1.x;
+ //Scan2Start := Src_Rect2.x + Left1 - Left2;
+ ScanWidth := Right2 - Left1;
+ with Src_Rect1 do
+ if ScanWidth > w then
+ ScanWidth := w;
+ end;
+ with SrcSurface1^ do
+ begin
+ Pitch1 := Pitch;
+ Addr1 := cardinal( Pixels );
+ inc( Addr1, Pitch1 * UInt32( Src_Rect1.y ) );
+ with format^ do
+ begin
+ BPP := BytesPerPixel;
+ TransparentColor1 := colorkey;
+ end;
+ end;
+
+ Mod1 := Pitch1 - ( ScanWidth * BPP );
+
+ inc( Addr1, BPP * Scan1Start );
+
+ if Top1 <= Top2 then
+ begin
+ // 1. up, 2. down
+ ScanHeight := Bottom1 - Top2;
+ if ScanHeight > Src_Rect2.h then
+ ScanHeight := Src_Rect2.h;
+ inc( Addr1, Pitch1 * UInt32( Top2 - Top1 ) );
+ end
+ else
+ begin
+ // 1. down, 2. up
+ ScanHeight := Bottom2 - Top1;
+ if ScanHeight > Src_Rect1.h then
+ ScanHeight := Src_Rect1.h;
+
+ end;
+ case BPP of
+ 1 :
+ for ty := 1 to ScanHeight do
+ begin
+ for tx := 1 to ScanWidth do
+ begin
+ if ( PByte( Addr1 )^ <> TransparentColor1 ) then
+ begin
+ Result := true;
+ exit;
+ end;
+ inc( Addr1 );
+
+ end;
+ inc( Addr1, Mod1 );
+
+ end;
+ 2 :
+ for ty := 1 to ScanHeight do
+ begin
+ for tx := 1 to ScanWidth do
+ begin
+ if ( PWord( Addr1 )^ <> TransparentColor1 ) then
+ begin
+ Result := true;
+ exit;
+ end;
+ inc( Addr1, 2 );
+
+ end;
+ inc( Addr1, Mod1 );
+
+ end;
+ 3 :
+ for ty := 1 to ScanHeight do
+ begin
+ for tx := 1 to ScanWidth do
+ begin
+ Color1 := PLongWord( Addr1 )^ and $00FFFFFF;
+
+ if ( Color1 <> TransparentColor1 )
+ then
+ begin
+ Result := true;
+ exit;
+ end;
+ inc( Addr1, 3 );
+
+ end;
+ inc( Addr1, Mod1 );
+
+ end;
+ 4 :
+ for ty := 1 to ScanHeight do
+ begin
+ for tx := 1 to ScanWidth do
+ begin
+ if ( PLongWord( Addr1 )^ <> TransparentColor1 ) then
+ begin
+ Result := true;
+ exit;
+ end;
+ inc( Addr1, 4 );
+
+ end;
+ inc( Addr1, Mod1 );
+
+ end;
+ end;
+end;
+
+procedure SDL_ORSurface( SrcSurface : PSDL_Surface; SrcRect : PSDL_Rect;
+ DestSurface : PSDL_Surface; DestRect : PSDL_Rect );
+var
+ R, G, B, Pixel1, Pixel2, TransparentColor : cardinal;
+ Src, Dest : TSDL_Rect;
+ Diff : integer;
+ SrcAddr, DestAddr : cardinal;
+ WorkX, WorkY : word;
+ SrcMod, DestMod : cardinal;
+ Bits : cardinal;
+begin
+ if ( SrcSurface = nil ) or ( DestSurface = nil ) then
+ exit; // Remove this to make it faster
+ if ( SrcSurface.Format.BitsPerPixel <> DestSurface.Format.BitsPerPixel ) then
+ exit; // Remove this to make it faster
+ if SrcRect = nil then
+ begin
+ with Src do
+ begin
+ x := 0;
+ y := 0;
+ w := SrcSurface.w;
+ h := SrcSurface.h;
+ end;
+ end
+ else
+ Src := SrcRect^;
+ if DestRect = nil then
+ begin
+ Dest.x := 0;
+ Dest.y := 0;
+ end
+ else
+ Dest := DestRect^;
+ Dest.w := Src.w;
+ Dest.h := Src.h;
+ with DestSurface.Clip_Rect do
+ begin
+ // Source's right side is greater than the dest.cliprect
+ if Dest.x + Src.w > x + w then
+ begin
+ smallint( Src.w ) := x + w - Dest.x;
+ smallint( Dest.w ) := x + w - Dest.x;
+ if smallint( Dest.w ) < 1 then
+ exit;
+ end;
+ // Source's bottom side is greater than the dest.clip
+ if Dest.y + Src.h > y + h then
+ begin
+ smallint( Src.h ) := y + h - Dest.y;
+ smallint( Dest.h ) := y + h - Dest.y;
+ if smallint( Dest.h ) < 1 then
+ exit;
+ end;
+ // Source's left side is less than the dest.clip
+ if Dest.x < x then
+ begin
+ Diff := x - Dest.x;
+ Src.x := Src.x + Diff;
+ smallint( Src.w ) := smallint( Src.w ) - Diff;
+ Dest.x := x;
+ smallint( Dest.w ) := smallint( Dest.w ) - Diff;
+ if smallint( Dest.w ) < 1 then
+ exit;
+ end;
+ // Source's Top side is less than the dest.clip
+ if Dest.y < y then
+ begin
+ Diff := y - Dest.y;
+ Src.y := Src.y + Diff;
+ smallint( Src.h ) := smallint( Src.h ) - Diff;
+ Dest.y := y;
+ smallint( Dest.h ) := smallint( Dest.h ) - Diff;
+ if smallint( Dest.h ) < 1 then
+ exit;
+ end;
+ end;
+ with SrcSurface^ do
+ begin
+ SrcAddr := cardinal( Pixels ) + UInt32( Src.y ) * Pitch + UInt32( Src.x ) *
+ Format.BytesPerPixel;
+ SrcMod := Pitch - Src.w * Format.BytesPerPixel;
+ TransparentColor := Format.colorkey;
+ end;
+ with DestSurface^ do
+ begin
+ DestAddr := cardinal( Pixels ) + UInt32( Dest.y ) * Pitch + UInt32( Dest.x ) *
+ Format.BytesPerPixel;
+ DestMod := Pitch - Dest.w * Format.BytesPerPixel;
+ Bits := Format.BitsPerPixel;
+ end;
+ SDL_LockSurface( SrcSurface );
+ SDL_LockSurface( DestSurface );
+ WorkY := Src.h;
+ case bits of
+ 8 :
+ begin
+ repeat
+ WorkX := Src.w;
+ repeat
+ Pixel1 := PUInt8( SrcAddr )^;
+ if ( Pixel1 <> TransparentColor ) and ( Pixel1 <> 0 ) then
+ begin
+ Pixel2 := PUInt8( DestAddr )^;
+ PUInt8( DestAddr )^ := Pixel2 or Pixel1;
+ end;
+ inc( SrcAddr );
+ inc( DestAddr );
+ dec( WorkX );
+ until WorkX = 0;
+ inc( SrcAddr, SrcMod );
+ inc( DestAddr, DestMod );
+ dec( WorkY );
+ until WorkY = 0;
+ end;
+ 15 :
+ begin
+ repeat
+ WorkX := Src.w;
+ repeat
+ Pixel1 := PUInt16( SrcAddr )^;
+ if ( Pixel1 <> TransparentColor ) and ( Pixel1 <> 0 ) then
+ begin
+ Pixel2 := PUInt16( DestAddr )^;
+
+ PUInt16( DestAddr )^ := Pixel2 or Pixel1;
+
+ end;
+ inc( SrcAddr, 2 );
+ inc( DestAddr, 2 );
+ dec( WorkX );
+ until WorkX = 0;
+ inc( SrcAddr, SrcMod );
+ inc( DestAddr, DestMod );
+ dec( WorkY );
+ until WorkY = 0;
+ end;
+ 16 :
+ begin
+ repeat
+ WorkX := Src.w;
+ repeat
+ Pixel1 := PUInt16( SrcAddr )^;
+ if ( Pixel1 <> TransparentColor ) and ( Pixel1 <> 0 ) then
+ begin
+ Pixel2 := PUInt16( DestAddr )^;
+
+ PUInt16( DestAddr )^ := Pixel2 or Pixel1;
+
+ end;
+ inc( SrcAddr, 2 );
+ inc( DestAddr, 2 );
+ dec( WorkX );
+ until WorkX = 0;
+ inc( SrcAddr, SrcMod );
+ inc( DestAddr, DestMod );
+ dec( WorkY );
+ until WorkY = 0;
+ end;
+ 24 :
+ begin
+ repeat
+ WorkX := Src.w;
+ repeat
+ Pixel1 := PUInt32( SrcAddr )^ and $00FFFFFF;
+ if ( Pixel1 <> TransparentColor ) and ( Pixel1 <> 0 ) then
+ begin
+ Pixel2 := PUInt32( DestAddr )^ and $00FFFFFF;
+
+ PUInt32( DestAddr )^ := PUInt32( DestAddr )^ and $FF000000 or Pixel2 or Pixel1;
+ end;
+ inc( SrcAddr, 3 );
+ inc( DestAddr, 3 );
+ dec( WorkX );
+ until WorkX = 0;
+ inc( SrcAddr, SrcMod );
+ inc( DestAddr, DestMod );
+ dec( WorkY );
+ until WorkY = 0;
+ end;
+ 32 :
+ begin
+ repeat
+ WorkX := Src.w;
+ repeat
+ Pixel1 := PUInt32( SrcAddr )^;
+ if ( Pixel1 <> TransparentColor ) and ( Pixel1 <> 0 ) then
+ begin
+ Pixel2 := PUInt32( DestAddr )^;
+
+ PUInt32( DestAddr )^ := Pixel2 or Pixel1;
+ end;
+ inc( SrcAddr, 4 );
+ inc( DestAddr, 4 );
+ dec( WorkX );
+ until WorkX = 0;
+ inc( SrcAddr, SrcMod );
+ inc( DestAddr, DestMod );
+ dec( WorkY );
+ until WorkY = 0;
+ end;
+ end;
+ SDL_UnlockSurface( SrcSurface );
+ SDL_UnlockSurface( DestSurface );
+end;
+
+procedure SDL_ANDSurface( SrcSurface : PSDL_Surface; SrcRect : PSDL_Rect;
+ DestSurface : PSDL_Surface; DestRect : PSDL_Rect );
+var
+ R, G, B, Pixel1, Pixel2, TransparentColor : cardinal;
+ Src, Dest : TSDL_Rect;
+ Diff : integer;
+ SrcAddr, DestAddr : cardinal;
+ WorkX, WorkY : word;
+ SrcMod, DestMod : cardinal;
+ Bits : cardinal;
+begin
+ if ( SrcSurface = nil ) or ( DestSurface = nil ) then
+ exit; // Remove this to make it faster
+ if ( SrcSurface.Format.BitsPerPixel <> DestSurface.Format.BitsPerPixel ) then
+ exit; // Remove this to make it faster
+ if SrcRect = nil then
+ begin
+ with Src do
+ begin
+ x := 0;
+ y := 0;
+ w := SrcSurface.w;
+ h := SrcSurface.h;
+ end;
+ end
+ else
+ Src := SrcRect^;
+ if DestRect = nil then
+ begin
+ Dest.x := 0;
+ Dest.y := 0;
+ end
+ else
+ Dest := DestRect^;
+ Dest.w := Src.w;
+ Dest.h := Src.h;
+ with DestSurface.Clip_Rect do
+ begin
+ // Source's right side is greater than the dest.cliprect
+ if Dest.x + Src.w > x + w then
+ begin
+ smallint( Src.w ) := x + w - Dest.x;
+ smallint( Dest.w ) := x + w - Dest.x;
+ if smallint( Dest.w ) < 1 then
+ exit;
+ end;
+ // Source's bottom side is greater than the dest.clip
+ if Dest.y + Src.h > y + h then
+ begin
+ smallint( Src.h ) := y + h - Dest.y;
+ smallint( Dest.h ) := y + h - Dest.y;
+ if smallint( Dest.h ) < 1 then
+ exit;
+ end;
+ // Source's left side is less than the dest.clip
+ if Dest.x < x then
+ begin
+ Diff := x - Dest.x;
+ Src.x := Src.x + Diff;
+ smallint( Src.w ) := smallint( Src.w ) - Diff;
+ Dest.x := x;
+ smallint( Dest.w ) := smallint( Dest.w ) - Diff;
+ if smallint( Dest.w ) < 1 then
+ exit;
+ end;
+ // Source's Top side is less than the dest.clip
+ if Dest.y < y then
+ begin
+ Diff := y - Dest.y;
+ Src.y := Src.y + Diff;
+ smallint( Src.h ) := smallint( Src.h ) - Diff;
+ Dest.y := y;
+ smallint( Dest.h ) := smallint( Dest.h ) - Diff;
+ if smallint( Dest.h ) < 1 then
+ exit;
+ end;
+ end;
+ with SrcSurface^ do
+ begin
+ SrcAddr := cardinal( Pixels ) + UInt32( Src.y ) * Pitch + UInt32( Src.x ) *
+ Format.BytesPerPixel;
+ SrcMod := Pitch - Src.w * Format.BytesPerPixel;
+ TransparentColor := Format.colorkey;
+ end;
+ with DestSurface^ do
+ begin
+ DestAddr := cardinal( Pixels ) + UInt32( Dest.y ) * Pitch + UInt32( Dest.x ) *
+ Format.BytesPerPixel;
+ DestMod := Pitch - Dest.w * Format.BytesPerPixel;
+ Bits := Format.BitsPerPixel;
+ end;
+ SDL_LockSurface( SrcSurface );
+ SDL_LockSurface( DestSurface );
+ WorkY := Src.h;
+ case bits of
+ 8 :
+ begin
+ repeat
+ WorkX := Src.w;
+ repeat
+ Pixel1 := PUInt8( SrcAddr )^;
+ if ( Pixel1 <> TransparentColor ) and ( Pixel1 <> 0 ) then
+ begin
+ Pixel2 := PUInt8( DestAddr )^;
+ PUInt8( DestAddr )^ := Pixel2 and Pixel1;
+ end;
+ inc( SrcAddr );
+ inc( DestAddr );
+ dec( WorkX );
+ until WorkX = 0;
+ inc( SrcAddr, SrcMod );
+ inc( DestAddr, DestMod );
+ dec( WorkY );
+ until WorkY = 0;
+ end;
+ 15 :
+ begin
+ repeat
+ WorkX := Src.w;
+ repeat
+ Pixel1 := PUInt16( SrcAddr )^;
+ if ( Pixel1 <> TransparentColor ) and ( Pixel1 <> 0 ) then
+ begin
+ Pixel2 := PUInt16( DestAddr )^;
+
+ PUInt16( DestAddr )^ := Pixel2 and Pixel1;
+
+ end;
+ inc( SrcAddr, 2 );
+ inc( DestAddr, 2 );
+ dec( WorkX );
+ until WorkX = 0;
+ inc( SrcAddr, SrcMod );
+ inc( DestAddr, DestMod );
+ dec( WorkY );
+ until WorkY = 0;
+ end;
+ 16 :
+ begin
+ repeat
+ WorkX := Src.w;
+ repeat
+ Pixel1 := PUInt16( SrcAddr )^;
+ if ( Pixel1 <> TransparentColor ) and ( Pixel1 <> 0 ) then
+ begin
+ Pixel2 := PUInt16( DestAddr )^;
+
+ PUInt16( DestAddr )^ := Pixel2 and Pixel1;
+
+ end;
+ inc( SrcAddr, 2 );
+ inc( DestAddr, 2 );
+ dec( WorkX );
+ until WorkX = 0;
+ inc( SrcAddr, SrcMod );
+ inc( DestAddr, DestMod );
+ dec( WorkY );
+ until WorkY = 0;
+ end;
+ 24 :
+ begin
+ repeat
+ WorkX := Src.w;
+ repeat
+ Pixel1 := PUInt32( SrcAddr )^ and $00FFFFFF;
+ if ( Pixel1 <> TransparentColor ) and ( Pixel1 <> 0 ) then
+ begin
+ Pixel2 := PUInt32( DestAddr )^ and $00FFFFFF;
+
+ PUInt32( DestAddr )^ := PUInt32( DestAddr )^ and $FF000000 or Pixel2 and Pixel1;
+ end;
+ inc( SrcAddr, 3 );
+ inc( DestAddr, 3 );
+ dec( WorkX );
+ until WorkX = 0;
+ inc( SrcAddr, SrcMod );
+ inc( DestAddr, DestMod );
+ dec( WorkY );
+ until WorkY = 0;
+ end;
+ 32 :
+ begin
+ repeat
+ WorkX := Src.w;
+ repeat
+ Pixel1 := PUInt32( SrcAddr )^;
+ if ( Pixel1 <> TransparentColor ) and ( Pixel1 <> 0 ) then
+ begin
+ Pixel2 := PUInt32( DestAddr )^;
+
+ PUInt32( DestAddr )^ := Pixel2 and Pixel1;
+ end;
+ inc( SrcAddr, 4 );
+ inc( DestAddr, 4 );
+ dec( WorkX );
+ until WorkX = 0;
+ inc( SrcAddr, SrcMod );
+ inc( DestAddr, DestMod );
+ dec( WorkY );
+ until WorkY = 0;
+ end;
+ end;
+ SDL_UnlockSurface( SrcSurface );
+ SDL_UnlockSurface( DestSurface );
+end;
+
+
+
+procedure SDL_GTSurface( SrcSurface : PSDL_Surface; SrcRect : PSDL_Rect;
+ DestSurface : PSDL_Surface; DestRect : PSDL_Rect );
+var
+ R, G, B, Pixel1, Pixel2, TransparentColor : cardinal;
+ Src, Dest : TSDL_Rect;
+ Diff : integer;
+ SrcAddr, DestAddr : cardinal;
+ WorkX, WorkY : word;
+ SrcMod, DestMod : cardinal;
+ Bits : cardinal;
+begin
+ if ( SrcSurface = nil ) or ( DestSurface = nil ) then
+ exit; // Remove this to make it faster
+ if ( SrcSurface.Format.BitsPerPixel <> DestSurface.Format.BitsPerPixel ) then
+ exit; // Remove this to make it faster
+ if SrcRect = nil then
+ begin
+ with Src do
+ begin
+ x := 0;
+ y := 0;
+ w := SrcSurface.w;
+ h := SrcSurface.h;
+ end;
+ end
+ else
+ Src := SrcRect^;
+ if DestRect = nil then
+ begin
+ Dest.x := 0;
+ Dest.y := 0;
+ end
+ else
+ Dest := DestRect^;
+ Dest.w := Src.w;
+ Dest.h := Src.h;
+ with DestSurface.Clip_Rect do
+ begin
+ // Source's right side is greater than the dest.cliprect
+ if Dest.x + Src.w > x + w then
+ begin
+ smallint( Src.w ) := x + w - Dest.x;
+ smallint( Dest.w ) := x + w - Dest.x;
+ if smallint( Dest.w ) < 1 then
+ exit;
+ end;
+ // Source's bottom side is greater than the dest.clip
+ if Dest.y + Src.h > y + h then
+ begin
+ smallint( Src.h ) := y + h - Dest.y;
+ smallint( Dest.h ) := y + h - Dest.y;
+ if smallint( Dest.h ) < 1 then
+ exit;
+ end;
+ // Source's left side is less than the dest.clip
+ if Dest.x < x then
+ begin
+ Diff := x - Dest.x;
+ Src.x := Src.x + Diff;
+ smallint( Src.w ) := smallint( Src.w ) - Diff;
+ Dest.x := x;
+ smallint( Dest.w ) := smallint( Dest.w ) - Diff;
+ if smallint( Dest.w ) < 1 then
+ exit;
+ end;
+ // Source's Top side is less than the dest.clip
+ if Dest.y < y then
+ begin
+ Diff := y - Dest.y;
+ Src.y := Src.y + Diff;
+ smallint( Src.h ) := smallint( Src.h ) - Diff;
+ Dest.y := y;
+ smallint( Dest.h ) := smallint( Dest.h ) - Diff;
+ if smallint( Dest.h ) < 1 then
+ exit;
+ end;
+ end;
+ with SrcSurface^ do
+ begin
+ SrcAddr := cardinal( Pixels ) + UInt32( Src.y ) * Pitch + UInt32( Src.x ) *
+ Format.BytesPerPixel;
+ SrcMod := Pitch - Src.w * Format.BytesPerPixel;
+ TransparentColor := Format.colorkey;
+ end;
+ with DestSurface^ do
+ begin
+ DestAddr := cardinal( Pixels ) + UInt32( Dest.y ) * Pitch + UInt32( Dest.x ) *
+ Format.BytesPerPixel;
+ DestMod := Pitch - Dest.w * Format.BytesPerPixel;
+ Bits := Format.BitsPerPixel;
+ end;
+ SDL_LockSurface( SrcSurface );
+ SDL_LockSurface( DestSurface );
+ WorkY := Src.h;
+ case bits of
+ 8 :
+ begin
+ repeat
+ WorkX := Src.w;
+ repeat
+ Pixel1 := PUInt8( SrcAddr )^;
+ if ( Pixel1 <> TransparentColor ) and ( Pixel1 <> 0 ) then
+ begin
+ Pixel2 := PUInt8( DestAddr )^;
+ if Pixel2 > 0 then
+ begin
+ if Pixel2 and $E0 > Pixel1 and $E0 then
+ R := Pixel2 and $E0
+ else
+ R := Pixel1 and $E0;
+ if Pixel2 and $1C > Pixel1 and $1C then
+ G := Pixel2 and $1C
+ else
+ G := Pixel1 and $1C;
+ if Pixel2 and $03 > Pixel1 and $03 then
+ B := Pixel2 and $03
+ else
+ B := Pixel1 and $03;
+
+ if R > $E0 then
+ R := $E0;
+ if G > $1C then
+ G := $1C;
+ if B > $03 then
+ B := $03;
+ PUInt8( DestAddr )^ := R or G or B;
+ end
+ else
+ PUInt8( DestAddr )^ := Pixel1;
+ end;
+ inc( SrcAddr );
+ inc( DestAddr );
+ dec( WorkX );
+ until WorkX = 0;
+ inc( SrcAddr, SrcMod );
+ inc( DestAddr, DestMod );
+ dec( WorkY );
+ until WorkY = 0;
+ end;
+ 15 :
+ begin
+ repeat
+ WorkX := Src.w;
+ repeat
+ Pixel1 := PUInt16( SrcAddr )^;
+ if ( Pixel1 <> TransparentColor ) and ( Pixel1 <> 0 ) then
+ begin
+ Pixel2 := PUInt16( DestAddr )^;
+ if Pixel2 > 0 then
+ begin
+
+ if Pixel2 and $7C00 > Pixel1 and $7C00 then
+ R := Pixel2 and $7C00
+ else
+ R := Pixel1 and $7C00;
+ if Pixel2 and $03E0 > Pixel1 and $03E0 then
+ G := Pixel2 and $03E0
+ else
+ G := Pixel1 and $03E0;
+ if Pixel2 and $001F > Pixel1 and $001F then
+ B := Pixel2 and $001F
+ else
+ B := Pixel1 and $001F;
+
+ PUInt16( DestAddr )^ := R or G or B;
+ end
+ else
+ PUInt16( DestAddr )^ := Pixel1;
+ end;
+ inc( SrcAddr, 2 );
+ inc( DestAddr, 2 );
+ dec( WorkX );
+ until WorkX = 0;
+ inc( SrcAddr, SrcMod );
+ inc( DestAddr, DestMod );
+ dec( WorkY );
+ until WorkY = 0;
+ end;
+ 16 :
+ begin
+ repeat
+ WorkX := Src.w;
+ repeat
+ Pixel1 := PUInt16( SrcAddr )^;
+ if ( Pixel1 <> TransparentColor ) and ( Pixel1 <> 0 ) then
+ begin
+ Pixel2 := PUInt16( DestAddr )^;
+ if Pixel2 > 0 then
+ begin
+
+ if Pixel2 and $F800 > Pixel1 and $F800 then
+ R := Pixel2 and $F800
+ else
+ R := Pixel1 and $F800;
+ if Pixel2 and $07E0 > Pixel1 and $07E0 then
+ G := Pixel2 and $07E0
+ else
+ G := Pixel1 and $07E0;
+ if Pixel2 and $001F > Pixel1 and $001F then
+ B := Pixel2 and $001F
+ else
+ B := Pixel1 and $001F;
+
+ PUInt16( DestAddr )^ := R or G or B;
+ end
+ else
+ PUInt16( DestAddr )^ := Pixel1;
+ end;
+ inc( SrcAddr, 2 );
+ inc( DestAddr, 2 );
+ dec( WorkX );
+ until WorkX = 0;
+ inc( SrcAddr, SrcMod );
+ inc( DestAddr, DestMod );
+ dec( WorkY );
+ until WorkY = 0;
+ end;
+ 24 :
+ begin
+ repeat
+ WorkX := Src.w;
+ repeat
+ Pixel1 := PUInt32( SrcAddr )^ and $00FFFFFF;
+ if ( Pixel1 <> TransparentColor ) and ( Pixel1 <> 0 ) then
+ begin
+ Pixel2 := PUInt32( DestAddr )^ and $00FFFFFF;
+ if Pixel2 > 0 then
+ begin
+
+ if Pixel2 and $FF0000 > Pixel1 and $FF0000 then
+ R := Pixel2 and $FF0000
+ else
+ R := Pixel1 and $FF0000;
+ if Pixel2 and $00FF00 > Pixel1 and $00FF00 then
+ G := Pixel2 and $00FF00
+ else
+ G := Pixel1 and $00FF00;
+ if Pixel2 and $0000FF > Pixel1 and $0000FF then
+ B := Pixel2 and $0000FF
+ else
+ B := Pixel1 and $0000FF;
+
+ PUInt32( DestAddr )^ := PUInt32( DestAddr )^ and $FF000000 or ( R or G or B );
+ end
+ else
+ PUInt32( DestAddr )^ := PUInt32( DestAddr )^ and $FF000000 or Pixel1;
+ end;
+ inc( SrcAddr, 3 );
+ inc( DestAddr, 3 );
+ dec( WorkX );
+ until WorkX = 0;
+ inc( SrcAddr, SrcMod );
+ inc( DestAddr, DestMod );
+ dec( WorkY );
+ until WorkY = 0;
+ end;
+ 32 :
+ begin
+ repeat
+ WorkX := Src.w;
+ repeat
+ Pixel1 := PUInt32( SrcAddr )^;
+ if ( Pixel1 <> TransparentColor ) and ( Pixel1 <> 0 ) then
+ begin
+ Pixel2 := PUInt32( DestAddr )^;
+ if Pixel2 > 0 then
+ begin
+
+ if Pixel2 and $FF0000 > Pixel1 and $FF0000 then
+ R := Pixel2 and $FF0000
+ else
+ R := Pixel1 and $FF0000;
+ if Pixel2 and $00FF00 > Pixel1 and $00FF00 then
+ G := Pixel2 and $00FF00
+ else
+ G := Pixel1 and $00FF00;
+ if Pixel2 and $0000FF > Pixel1 and $0000FF then
+ B := Pixel2 and $0000FF
+ else
+ B := Pixel1 and $0000FF;
+
+ PUInt32( DestAddr )^ := R or G or B;
+ end
+ else
+ PUInt32( DestAddr )^ := Pixel1;
+ end;
+ inc( SrcAddr, 4 );
+ inc( DestAddr, 4 );
+ dec( WorkX );
+ until WorkX = 0;
+ inc( SrcAddr, SrcMod );
+ inc( DestAddr, DestMod );
+ dec( WorkY );
+ until WorkY = 0;
+ end;
+ end;
+ SDL_UnlockSurface( SrcSurface );
+ SDL_UnlockSurface( DestSurface );
+end;
+
+
+procedure SDL_LTSurface( SrcSurface : PSDL_Surface; SrcRect : PSDL_Rect;
+ DestSurface : PSDL_Surface; DestRect : PSDL_Rect );
+var
+ R, G, B, Pixel1, Pixel2, TransparentColor : cardinal;
+ Src, Dest : TSDL_Rect;
+ Diff : integer;
+ SrcAddr, DestAddr : cardinal;
+ WorkX, WorkY : word;
+ SrcMod, DestMod : cardinal;
+ Bits : cardinal;
+begin
+ if ( SrcSurface = nil ) or ( DestSurface = nil ) then
+ exit; // Remove this to make it faster
+ if ( SrcSurface.Format.BitsPerPixel <> DestSurface.Format.BitsPerPixel ) then
+ exit; // Remove this to make it faster
+ if SrcRect = nil then
+ begin
+ with Src do
+ begin
+ x := 0;
+ y := 0;
+ w := SrcSurface.w;
+ h := SrcSurface.h;
+ end;
+ end
+ else
+ Src := SrcRect^;
+ if DestRect = nil then
+ begin
+ Dest.x := 0;
+ Dest.y := 0;
+ end
+ else
+ Dest := DestRect^;
+ Dest.w := Src.w;
+ Dest.h := Src.h;
+ with DestSurface.Clip_Rect do
+ begin
+ // Source's right side is greater than the dest.cliprect
+ if Dest.x + Src.w > x + w then
+ begin
+ smallint( Src.w ) := x + w - Dest.x;
+ smallint( Dest.w ) := x + w - Dest.x;
+ if smallint( Dest.w ) < 1 then
+ exit;
+ end;
+ // Source's bottom side is greater than the dest.clip
+ if Dest.y + Src.h > y + h then
+ begin
+ smallint( Src.h ) := y + h - Dest.y;
+ smallint( Dest.h ) := y + h - Dest.y;
+ if smallint( Dest.h ) < 1 then
+ exit;
+ end;
+ // Source's left side is less than the dest.clip
+ if Dest.x < x then
+ begin
+ Diff := x - Dest.x;
+ Src.x := Src.x + Diff;
+ smallint( Src.w ) := smallint( Src.w ) - Diff;
+ Dest.x := x;
+ smallint( Dest.w ) := smallint( Dest.w ) - Diff;
+ if smallint( Dest.w ) < 1 then
+ exit;
+ end;
+ // Source's Top side is less than the dest.clip
+ if Dest.y < y then
+ begin
+ Diff := y - Dest.y;
+ Src.y := Src.y + Diff;
+ smallint( Src.h ) := smallint( Src.h ) - Diff;
+ Dest.y := y;
+ smallint( Dest.h ) := smallint( Dest.h ) - Diff;
+ if smallint( Dest.h ) < 1 then
+ exit;
+ end;
+ end;
+ with SrcSurface^ do
+ begin
+ SrcAddr := cardinal( Pixels ) + UInt32( Src.y ) * Pitch + UInt32( Src.x ) *
+ Format.BytesPerPixel;
+ SrcMod := Pitch - Src.w * Format.BytesPerPixel;
+ TransparentColor := Format.colorkey;
+ end;
+ with DestSurface^ do
+ begin
+ DestAddr := cardinal( Pixels ) + UInt32( Dest.y ) * Pitch + UInt32( Dest.x ) *
+ Format.BytesPerPixel;
+ DestMod := Pitch - Dest.w * Format.BytesPerPixel;
+ Bits := Format.BitsPerPixel;
+ end;
+ SDL_LockSurface( SrcSurface );
+ SDL_LockSurface( DestSurface );
+ WorkY := Src.h;
+ case bits of
+ 8 :
+ begin
+ repeat
+ WorkX := Src.w;
+ repeat
+ Pixel1 := PUInt8( SrcAddr )^;
+ if ( Pixel1 <> TransparentColor ) and ( Pixel1 <> 0 ) then
+ begin
+ Pixel2 := PUInt8( DestAddr )^;
+ if Pixel2 > 0 then
+ begin
+ if Pixel2 and $E0 < Pixel1 and $E0 then
+ R := Pixel2 and $E0
+ else
+ R := Pixel1 and $E0;
+ if Pixel2 and $1C < Pixel1 and $1C then
+ G := Pixel2 and $1C
+ else
+ G := Pixel1 and $1C;
+ if Pixel2 and $03 < Pixel1 and $03 then
+ B := Pixel2 and $03
+ else
+ B := Pixel1 and $03;
+
+ if R > $E0 then
+ R := $E0;
+ if G > $1C then
+ G := $1C;
+ if B > $03 then
+ B := $03;
+ PUInt8( DestAddr )^ := R or G or B;
+ end
+ else
+ PUInt8( DestAddr )^ := Pixel1;
+ end;
+ inc( SrcAddr );
+ inc( DestAddr );
+ dec( WorkX );
+ until WorkX = 0;
+ inc( SrcAddr, SrcMod );
+ inc( DestAddr, DestMod );
+ dec( WorkY );
+ until WorkY = 0;
+ end;
+ 15 :
+ begin
+ repeat
+ WorkX := Src.w;
+ repeat
+ Pixel1 := PUInt16( SrcAddr )^;
+ if ( Pixel1 <> TransparentColor ) and ( Pixel1 <> 0 ) then
+ begin
+ Pixel2 := PUInt16( DestAddr )^;
+ if Pixel2 > 0 then
+ begin
+
+ if Pixel2 and $7C00 < Pixel1 and $7C00 then
+ R := Pixel2 and $7C00
+ else
+ R := Pixel1 and $7C00;
+ if Pixel2 and $03E0 < Pixel1 and $03E0 then
+ G := Pixel2 and $03E0
+ else
+ G := Pixel1 and $03E0;
+ if Pixel2 and $001F < Pixel1 and $001F then
+ B := Pixel2 and $001F
+ else
+ B := Pixel1 and $001F;
+
+ PUInt16( DestAddr )^ := R or G or B;
+ end
+ else
+ PUInt16( DestAddr )^ := Pixel1;
+ end;
+ inc( SrcAddr, 2 );
+ inc( DestAddr, 2 );
+ dec( WorkX );
+ until WorkX = 0;
+ inc( SrcAddr, SrcMod );
+ inc( DestAddr, DestMod );
+ dec( WorkY );
+ until WorkY = 0;
+ end;
+ 16 :
+ begin
+ repeat
+ WorkX := Src.w;
+ repeat
+ Pixel1 := PUInt16( SrcAddr )^;
+ if ( Pixel1 <> TransparentColor ) and ( Pixel1 <> 0 ) then
+ begin
+ Pixel2 := PUInt16( DestAddr )^;
+ if Pixel2 > 0 then
+ begin
+
+ if Pixel2 and $F800 < Pixel1 and $F800 then
+ R := Pixel2 and $F800
+ else
+ R := Pixel1 and $F800;
+ if Pixel2 and $07E0 < Pixel1 and $07E0 then
+ G := Pixel2 and $07E0
+ else
+ G := Pixel1 and $07E0;
+ if Pixel2 and $001F < Pixel1 and $001F then
+ B := Pixel2 and $001F
+ else
+ B := Pixel1 and $001F;
+
+ PUInt16( DestAddr )^ := R or G or B;
+ end
+ else
+ PUInt16( DestAddr )^ := Pixel1;
+ end;
+ inc( SrcAddr, 2 );
+ inc( DestAddr, 2 );
+ dec( WorkX );
+ until WorkX = 0;
+ inc( SrcAddr, SrcMod );
+ inc( DestAddr, DestMod );
+ dec( WorkY );
+ until WorkY = 0;
+ end;
+ 24 :
+ begin
+ repeat
+ WorkX := Src.w;
+ repeat
+ Pixel1 := PUInt32( SrcAddr )^ and $00FFFFFF;
+ if ( Pixel1 <> TransparentColor ) and ( Pixel1 <> 0 ) then
+ begin
+ Pixel2 := PUInt32( DestAddr )^ and $00FFFFFF;
+ if Pixel2 > 0 then
+ begin
+
+ if Pixel2 and $FF0000 < Pixel1 and $FF0000 then
+ R := Pixel2 and $FF0000
+ else
+ R := Pixel1 and $FF0000;
+ if Pixel2 and $00FF00 < Pixel1 and $00FF00 then
+ G := Pixel2 and $00FF00
+ else
+ G := Pixel1 and $00FF00;
+ if Pixel2 and $0000FF < Pixel1 and $0000FF then
+ B := Pixel2 and $0000FF
+ else
+ B := Pixel1 and $0000FF;
+
+ PUInt32( DestAddr )^ := PUInt32( DestAddr )^ and $FF000000 or ( R or G or B );
+ end
+ else
+ PUInt32( DestAddr )^ := PUInt32( DestAddr )^ and $FF000000 or Pixel1;
+ end;
+ inc( SrcAddr, 3 );
+ inc( DestAddr, 3 );
+ dec( WorkX );
+ until WorkX = 0;
+ inc( SrcAddr, SrcMod );
+ inc( DestAddr, DestMod );
+ dec( WorkY );
+ until WorkY = 0;
+ end;
+ 32 :
+ begin
+ repeat
+ WorkX := Src.w;
+ repeat
+ Pixel1 := PUInt32( SrcAddr )^;
+ if ( Pixel1 <> TransparentColor ) and ( Pixel1 <> 0 ) then
+ begin
+ Pixel2 := PUInt32( DestAddr )^;
+ if Pixel2 > 0 then
+ begin
+
+ if Pixel2 and $FF0000 < Pixel1 and $FF0000 then
+ R := Pixel2 and $FF0000
+ else
+ R := Pixel1 and $FF0000;
+ if Pixel2 and $00FF00 < Pixel1 and $00FF00 then
+ G := Pixel2 and $00FF00
+ else
+ G := Pixel1 and $00FF00;
+ if Pixel2 and $0000FF < Pixel1 and $0000FF then
+ B := Pixel2 and $0000FF
+ else
+ B := Pixel1 and $0000FF;
+
+ PUInt32( DestAddr )^ := R or G or B;
+ end
+ else
+ PUInt32( DestAddr )^ := Pixel1;
+ end;
+ inc( SrcAddr, 4 );
+ inc( DestAddr, 4 );
+ dec( WorkX );
+ until WorkX = 0;
+ inc( SrcAddr, SrcMod );
+ inc( DestAddr, DestMod );
+ dec( WorkY );
+ until WorkY = 0;
+ end;
+ end;
+ SDL_UnlockSurface( SrcSurface );
+ SDL_UnlockSurface( DestSurface );
+end;
+
+// Will clip the x1,x2,y1,x2 params to the ClipRect provided
+
+function SDL_ClipLine( var x1, y1, x2, y2 : Integer; ClipRect : PSDL_Rect ) : boolean;
+var
+ tflag, flag1, flag2 : word;
+ txy, xedge, yedge : Integer;
+ slope : single;
+
+ function ClipCode( x, y : Integer ) : word;
+ begin
+ Result := 0;
+ if x < ClipRect.x then
+ Result := 1;
+ if x >= ClipRect.w + ClipRect.x then
+ Result := Result or 2;
+ if y < ClipRect.y then
+ Result := Result or 4;
+ if y >= ClipRect.h + ClipRect.y then
+ Result := Result or 8;
+ end;
+
+begin
+ flag1 := ClipCode( x1, y1 );
+ flag2 := ClipCode( x2, y2 );
+ result := true;
+
+ while true do
+ begin
+ if ( flag1 or flag2 ) = 0 then
+ Exit; // all in
+
+ if ( flag1 and flag2 ) <> 0 then
+ begin
+ result := false;
+ Exit; // all out
+ end;
+
+ if flag2 = 0 then
+ begin
+ txy := x1; x1 := x2; x2 := txy;
+ txy := y1; y1 := y2; y2 := txy;
+ tflag := flag1; flag1 := flag2; flag2 := tflag;
+ end;
+
+ if ( flag2 and 3 ) <> 0 then
+ begin
+ if ( flag2 and 1 ) <> 0 then
+ xedge := ClipRect.x
+ else
+ xedge := ClipRect.w + ClipRect.x - 1; // back 1 pixel otherwise we end up in a loop
+
+ slope := ( y2 - y1 ) / ( x2 - x1 );
+ y2 := y1 + Round( slope * ( xedge - x1 ) );
+ x2 := xedge;
+ end
+ else
+ begin
+ if ( flag2 and 4 ) <> 0 then
+ yedge := ClipRect.y
+ else
+ yedge := ClipRect.h + ClipRect.y - 1; // up 1 pixel otherwise we end up in a loop
+
+ slope := ( x2 - x1 ) / ( y2 - y1 );
+ x2 := x1 + Round( slope * ( yedge - y1 ) );
+ y2 := yedge;
+ end;
+
+ flag2 := ClipCode( x2, y2 );
+ end;
+end;
+
+end.
+
diff --git a/packages/sdl/src/smpeg.pas b/packages/sdl/src/smpeg.pas
new file mode 100644
index 0000000000..af6913e3aa
--- /dev/null
+++ b/packages/sdl/src/smpeg.pas
@@ -0,0 +1,435 @@
+unit smpeg;
+{******************************************************************************}
+{
+ $Id: smpeg.pas,v 1.7 2004/08/14 22:54:30 savage Exp $
+
+}
+{ }
+{ Borland Delphi SMPEG - SDL MPEG Player Library }
+{ Conversion of the SMPEG - SDL MPEG Player Library }
+{ }
+{ Portions created by Sam Lantinga <slouken@devolution.com> are }
+{ Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga }
+{ 5635-34 Springhouse Dr. }
+{ Pleasanton, CA 94588 (USA) }
+{ }
+{ All Rights Reserved. }
+{ }
+{ The original files are : smpeg.h }
+{ }
+{ The initial developer of this Pascal code was : }
+{ Matthias Thoma <ma.thoma@gmx.de> }
+{ }
+{ Portions created by Matthias Thoma are }
+{ Copyright (C) 2000 - 2001 Matthias Thoma. }
+{ }
+{ }
+{ Contributor(s) }
+{ -------------- }
+{ Tom Jones <tigertomjones@gmx.de> His Project inspired this conversion }
+{ Matthias Thoma <ma.thoma@gmx.de> }
+{ }
+{ Obtained through: }
+{ Joint Endeavour of Delphi Innovators ( Project JEDI ) }
+{ }
+{ You may retrieve the latest version of this file at the Project }
+{ JEDI home page, located at http://delphi-jedi.org }
+{ }
+{ The contents of this file are used with permission, subject to }
+{ the Mozilla Public License Version 1.1 (the "License"); you may }
+{ not use this file except in compliance with the License. You may }
+{ obtain a copy of the License at }
+{ http://www.mozilla.org/MPL/MPL-1.1.html }
+{ }
+{ Software distributed under the License is distributed on an }
+{ "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or }
+{ implied. See the License for the specific language governing }
+{ rights and limitations under the License. }
+{ }
+{ Description }
+{ ----------- }
+{ }
+{ }
+{ }
+{ }
+{ }
+{ }
+{ }
+{ Requires }
+{ -------- }
+{ The SDL Runtime libraris on Win32 : SDL.dll on Linux : libSDL-1.2.so.0 }
+{ They are available from... }
+{ http://www.libsdl.org . }
+{ }
+{ Programming Notes }
+{ ----------------- }
+{ }
+{ }
+{ }
+{ }
+{ Revision History }
+{ ---------------- }
+{ May 08 2001 - MT : Initial conversion }
+{ }
+{ October 12 2001 - DA : Various changes as suggested by David Acklam }
+{ }
+{ April 03 2003 - DL : Added jedi-sdl.inc include file to support more }
+{ Pascal compilers. Initial support is now included }
+{ for GnuPascal, VirtualPascal, TMT and obviously }
+{ continue support for Delphi Kylix and FreePascal. }
+{ }
+{ April 08 2003 - MK : Aka Mr Kroket - Added Better FPC support }
+{ Fixed all invalid calls to DLL. }
+{ Changed constant names to: }
+{ const }
+{ STATUS_SMPEG_ERROR = -1; }
+{ STATUS_SMPEG_STOPPED = 0; }
+{ STATUS_SMPEG_PLAYING = 1; }
+{ because SMPEG_ERROR is a function (_SMPEG_error }
+{ isn't correct), and cannot be two elements with the }
+{ same name }
+{ }
+{ April 24 2003 - DL : under instruction from Alexey Barkovoy, I have added}
+{ better TMT Pascal support and under instruction }
+{ from Prof. Abimbola Olowofoyeku (The African Chief),}
+{ I have added better Gnu Pascal support }
+{ }
+{ April 30 2003 - DL : under instruction from David Mears AKA }
+{ Jason Siletto, I have added FPC Linux support. }
+{ This was compiled with fpc 1.1, so remember to set }
+{ include file path. ie. -Fi/usr/share/fpcsrc/rtl/* }
+{ }
+{
+ $Log: smpeg.pas,v $
+ Revision 1.7 2004/08/14 22:54:30 savage
+ Updated so that Library name defines are correctly defined for MacOS X.
+
+ Revision 1.6 2004/05/10 14:10:04 savage
+ Initial MacOS X support. Fixed defines for MACOS ( Classic ) and DARWIN ( MacOS X ).
+
+ Revision 1.5 2004/04/13 09:32:08 savage
+ Changed Shared object names back to just the .so extension to avoid conflicts on various Linux/Unix distros. Therefore developers will need to create Symbolic links to the actual Share Objects if necessary.
+
+ Revision 1.4 2004/04/02 10:40:55 savage
+ Changed Linux Shared Object name so they reflect the Symbolic Links that are created when installing the RPMs from the SDL site.
+
+ Revision 1.3 2004/03/31 22:20:02 savage
+ Windows unit not used in this file, so it was removed to keep the code tidy.
+
+ Revision 1.2 2004/03/30 20:23:28 savage
+ Tidied up use of UNIX compiler directive.
+
+ Revision 1.1 2004/02/14 23:35:42 savage
+ version 1 of sdl_image, sdl_mixer and smpeg.
+
+
+}
+{******************************************************************************}
+
+{$I jedi-sdl.inc}
+
+interface
+
+uses
+{$IFDEF __GPC__}
+ gpc,
+{$ENDIF}
+
+ sdl;
+
+const
+{$IFDEF windows}
+ SmpegLibName = 'smpeg.dll';
+{$ENDIF}
+
+{$IFDEF UNIX}
+{$IFDEF DARWIN}
+ SmpegLibName = 'libsmpeg.dylib';
+{$ELSE}
+ SmpegLibName = 'libsmpeg.so';
+{$ENDIF}
+{$ENDIF}
+
+{$IFDEF MACOS}
+ SmpegLibName = 'smpeg';
+{$ENDIF}
+
+//------------------------------------------------------------------------------
+// MPEGFilter.h
+//------------------------------------------------------------------------------
+{ SMPEG filter info flags }
+const
+ SMPEG_FILTER_INFO_MB_ERROR = 1;
+ SMPEG_FILTER_INFO_PIXEL_ERROR = 2;
+
+{ Filter info from SMPEG }
+type
+ SMPEG_FilterInfo = record
+ yuv_mb_square_error: PUint16;
+ yuv_pixel_square_error: PUint16;
+ end;
+ TSMPEG_FilterInfo = SMPEG_FilterInfo;
+ PSMPEG_FilterInfo = ^SMPEG_FilterInfo;
+
+{ MPEG filter definition }
+ PSMPEG_Filter = ^TSMPEG_Filter;
+
+{ Callback functions for the filter }
+ {$IFNDEF __GPC__}
+ TSMPEG_FilterCallback = function( dest, source: PSDL_Overlay; region: PSDL_Rect; filter_info: PSMPEG_FilterInfo; data: Pointer ): Pointer; cdecl;
+ {$ELSE}
+ TSMPEG_FilterCallback = function( dest, source: PSDL_Overlay; region: PSDL_Rect; filter_info: PSMPEG_FilterInfo; data: Pointer ): Pointer;
+ {$ENDIF}
+
+ {$IFNDEF __GPC__}
+ TSMPEG_FilterDestroy = function( Filter: PSMPEG_Filter ): Pointer; cdecl;
+ {$ELSE}
+ TSMPEG_FilterDestroy = function( Filter: PSMPEG_Filter ): Pointer;
+ {$ENDIF}
+
+{ The filter definition itself }
+ TSMPEG_Filter = record
+ flags: Uint32;
+ data: Pointer;
+ callback: TSMPEG_FilterCallback;
+ destroy: TSMPEG_FilterDestroy;
+ end;
+
+{ The null filter (default). It simply copies the source rectangle to the video overlay. }
+function SMPEGfilter_null: PSMPEG_Filter;
+cdecl; external {$IFDEF __GPC__}name 'SMPEGfilter_null'{$ELSE} SmpegLibName{$ENDIF __GPC__};
+
+{ The bilinear filter. A basic low-pass filter that will produce a smoother image. }
+function SMPEGfilter_bilinear: PSMPEG_Filter;
+cdecl; external {$IFDEF __GPC__}name 'SMPEGfilter_bilinear'{$ELSE} SmpegLibName{$ENDIF __GPC__};
+
+{ The deblocking filter. It filters block borders and non-intra coded blocks to reduce blockiness }
+function SMPEGfilter_deblocking: PSMPEG_Filter;
+cdecl; external {$IFDEF __GPC__}name 'SMPEGfilter_deblocking'{$ELSE} SmpegLibName{$ENDIF __GPC__};
+
+//------------------------------------------------------------------------------
+// SMPEG.h
+//------------------------------------------------------------------------------
+const
+ SMPEG_MAJOR_VERSION = 0;
+ SMPEG_MINOR_VERSION = 4;
+ SMPEG_PATCHLEVEL = 2;
+
+type
+ SMPEG_version = record
+ major: UInt8;
+ minor: UInt8;
+ patch: UInt8;
+ end;
+ TSMPEG_version = SMPEG_version;
+ PSMPEG_version = ^TSMPEG_version;
+
+ // This is the actual SMPEG object
+ _SMPEG = record
+ //obj: PMPEG;
+ end;
+ TSMPEG = _SMPEG;
+ PSMPEG = ^_SMPEG;
+
+ { Used to get information about the SMPEG object }
+ __SMPEG_Info = record
+ has_audio: Integer;
+ has_video: Integer;
+ width: Integer;
+ height: Integer;
+ current_frame: Integer;
+ current_fps: double;
+ audio_string: array[0..79] of char;
+ audio_current_frame: Integer;
+ current_offset: UInt32;
+ total_size: UInt32;
+ current_time: double;
+ total_time: double;
+ end;
+ _SMPEG_Info = __SMPEG_Info;
+ SMPEG_Info = _SMPEG_Info;
+ TSMPEG_Info = _SMPEG_Info;
+ PSMPEG_Info = ^_SMPEG_Info;
+
+{ Possible MPEG status codes }
+const
+ STATUS_SMPEG_ERROR = -1;
+ STATUS_SMPEG_STOPPED = 0;
+ STATUS_SMPEG_PLAYING = 1;
+
+type
+ SMPEGstatus = Integer;
+ TSMPEGstatus = Integer;
+ PSMPEGstatus = ^Integer;
+
+ { Matches the declaration of SDL_UpdateRect() }
+ {$IFNDEF __GPC__}
+ TSMPEG_DisplayCallback = function( dst: PSDL_Surface; x, y: Integer; w, h: Cardinal ): Pointer; cdecl;
+ {$ELSE}
+ TSMPEG_DisplayCallback = function( dst: PSDL_Surface; x, y: Integer; w, h: Cardinal ): Pointer;
+ {$ENDIF}
+
+
+{ Create a new SMPEG object from an MPEG file.
+ On return, if 'info' is not NULL, it will be filled with information
+ about the MPEG object.
+ This function returns a new SMPEG object. Use SMPEG_error() to find out
+ whether or not there was a problem building the MPEG stream.
+ The sdl_audio parameter indicates if SMPEG should initialize the SDL audio
+ subsystem. If not, you will have to use the SMPEG_playaudio() function below
+ to extract the decoded data. }
+function SMPEG_new(const _file: PChar; info: PSMPEG_Info; sdl_audio: Integer): PSMPEG;
+cdecl; external {$IFDEF __GPC__}name 'SMPEG_new'{$ELSE} SmpegLibName{$ENDIF __GPC__};
+
+{ The same as above for a file descriptor }
+function SMPEG_new_descr(_file: Integer; info: PSMPEG_Info; sdl_audio: Integer): PSMPEG;
+cdecl; external {$IFDEF __GPC__}name 'SMPEG_new_descr'{$ELSE} SmpegLibName{$ENDIF __GPC__};
+
+{ The same as above but for a raw chunk of data. SMPEG makes a copy of the
+ data, so the application is free to delete after a successful call to this
+ function. }
+function SMPEG_new_data(data: Pointer; size: Integer; info: PSMPEG_Info; sdl_audio: Integer): PSMPEG;
+cdecl; external {$IFDEF __GPC__}name 'SMPEG_new_data'{$ELSE} SmpegLibName{$ENDIF __GPC__};
+
+{ Get current information about an SMPEG object }
+procedure SMPEG_getinfo(mpeg: PSMPEG; info: PSMPEG_Info);
+cdecl; external {$IFDEF __GPC__}name 'SMPEG_getinfo'{$ELSE} SmpegLibName{$ENDIF __GPC__};
+
+//procedure SMPEG_getinfo(mpeg: PSMPEG; info: Pointer);
+//cdecl; external {$IFDEF __GPC__}name 'SMPEG_getinfo'{$ELSE} SmpegLibName{$ENDIF __GPC__};
+{ Enable or disable audio playback in MPEG stream }
+procedure SMPEG_enableaudio(mpeg: PSMPEG; enable: Integer);
+cdecl; external {$IFDEF __GPC__}name 'SMPEG_enableaudio'{$ELSE} SmpegLibName{$ENDIF __GPC__};
+
+{ Enable or disable video playback in MPEG stream }
+procedure SMPEG_enablevideo(mpeg: PSMPEG; enable: Integer);
+cdecl; external {$IFDEF __GPC__}name 'SMPEG_enablevideo'{$ELSE} SmpegLibName{$ENDIF __GPC__};
+
+{ Delete an SMPEG object }
+procedure SMPEG_delete(mpeg: PSMPEG);
+cdecl; external {$IFDEF __GPC__}name 'SMPEG_delete'{$ELSE} SmpegLibName{$ENDIF __GPC__};
+
+{ Get the current status of an SMPEG object }
+function SMPEG_status(mpeg: PSMPEG): TSMPEGstatus;
+cdecl; external {$IFDEF __GPC__}name 'SMPEG_status'{$ELSE} SmpegLibName{$ENDIF __GPC__};
+ // status
+{ Set the audio volume of an MPEG stream, in the range 0-100 }
+procedure SMPEG_setvolume(mpeg: PSMPEG; volume: Integer);
+cdecl; external {$IFDEF __GPC__}name 'SMPEG_setvolume'{$ELSE} SmpegLibName{$ENDIF __GPC__};
+
+{ Set the destination surface for MPEG video playback
+ 'surfLock' is a mutex used to synchronize access to 'dst', and can be NULL.
+ 'callback' is a function called when an area of 'dst' needs to be updated.
+ If 'callback' is NULL, the default function (SDL_UpdateRect) will be used. }
+procedure SMPEG_setdisplay(mpeg: PSMPEG; dst: PSDL_Surface; surfLock: PSDL_mutex; callback: TSMPEG_DisplayCallback);
+cdecl; external {$IFDEF __GPC__}name 'SMPEG_setdisplay'{$ELSE} SmpegLibName{$ENDIF __GPC__};
+
+{ Set or clear looping play on an SMPEG object }
+procedure SMPEG_loop(mpeg: PSMPEG; _repeat: Integer);
+cdecl; external {$IFDEF __GPC__}name 'SMPEG_loop'{$ELSE} SmpegLibName{$ENDIF __GPC__};
+
+{ Scale pixel display on an SMPEG object }
+procedure SMPEG_scaleXY(mpeg: PSMPEG; width, height: Integer);
+cdecl; external {$IFDEF __GPC__}name 'SMPEG_scaleXY'{$ELSE} SmpegLibName{$ENDIF __GPC__};
+procedure SMPEG_scale(mpeg: PSMPEG; scale: Integer);
+cdecl; external {$IFDEF __GPC__}name 'SMPEG_scale'{$ELSE} SmpegLibName{$ENDIF __GPC__};
+
+procedure SMPEG_Double(mpeg : PSMPEG; doubleit : Boolean );
+
+{ Move the video display area within the destination surface }
+procedure SMPEG_move(mpeg: PSMPEG; x, y: Integer);
+cdecl; external {$IFDEF __GPC__}name 'SMPEG_move'{$ELSE} SmpegLibName{$ENDIF __GPC__};
+
+{ Set the region of the video to be shown }
+procedure SMPEG_setdisplayregion(mpeg: PSMPEG; x, y, w, h: Integer);
+cdecl; external {$IFDEF __GPC__}name 'SMPEG_setdisplayregion'{$ELSE} SmpegLibName{$ENDIF __GPC__};
+
+{ Play an SMPEG object }
+procedure SMPEG_play(mpeg: PSMPEG);
+cdecl; external {$IFDEF __GPC__}name 'SMPEG_play'{$ELSE} SmpegLibName{$ENDIF __GPC__};
+
+{ Pause/Resume playback of an SMPEG object}
+procedure SMPEG_pause(mpeg: PSMPEG);
+cdecl; external {$IFDEF __GPC__}name 'SMPEG_pause'{$ELSE} SmpegLibName{$ENDIF __GPC__};
+
+{ Stop playback of an SMPEG object }
+procedure SMPEG_stop(mpeg: PSMPEG);
+cdecl; external {$IFDEF __GPC__}name 'SMPEG_stop'{$ELSE} SmpegLibName{$ENDIF __GPC__};
+
+{ Rewind the play position of an SMPEG object to the beginning of the MPEG }
+procedure SMPEG_rewind(mpeg: PSMPEG);
+cdecl; external {$IFDEF __GPC__}name 'SMPEG_rewind'{$ELSE} SmpegLibName{$ENDIF __GPC__};
+
+{ Seek 'bytes' bytes in the MPEG stream }
+procedure SMPEG_seek(mpeg: PSMPEG; bytes: Integer);
+cdecl; external {$IFDEF __GPC__}name 'SMPEG_seek'{$ELSE} SmpegLibName{$ENDIF __GPC__};
+
+{ Skip 'seconds' seconds in the MPEG stream }
+procedure SMPEG_skip(mpeg: PSMPEG; seconds: single);
+cdecl; external {$IFDEF __GPC__}name 'SMPEG_skip'{$ELSE} SmpegLibName{$ENDIF __GPC__};
+
+{ Render a particular frame in the MPEG video
+ API CHANGE: This function no longer takes a target surface and position.
+ Use SMPEG_setdisplay() and SMPEG_move() to set this information. }
+procedure SMPEG_renderFrame(mpeg: PSMPEG; framenum: Integer);
+cdecl; external {$IFDEF __GPC__}name 'SMPEG_renderFrame'{$ELSE} SmpegLibName{$ENDIF __GPC__};
+
+{ Render the last frame of an MPEG video }
+procedure SMPEG_renderFinal(mpeg: PSMPEG; dst: PSDL_Surface; x, y: Integer);
+cdecl; external {$IFDEF __GPC__}name 'SMPEG_renderFinal'{$ELSE} SmpegLibName{$ENDIF __GPC__};
+
+{ Set video filter }
+function SMPEG_filter(mpeg: PSMPEG; filter: PSMPEG_Filter): PSMPEG_Filter;
+cdecl; external {$IFDEF __GPC__}name 'SMPEG_filter'{$ELSE} SmpegLibName{$ENDIF __GPC__};
+
+{ Return NULL if there is no error in the MPEG stream, or an error message
+ if there was a fatal error in the MPEG stream for the SMPEG object. }
+function SMPEG_error(mpeg: PSMPEG): PChar;
+cdecl; external {$IFDEF __GPC__}name 'SMPEG_error'{$ELSE} SmpegLibName{$ENDIF __GPC__};
+
+{ Exported callback function for audio playback.
+ The function takes a buffer and the amount of data to fill, and returns
+ the amount of data in bytes that was actually written. This will be the
+ amount requested unless the MPEG audio has finished.
+}
+function SMPEG_playAudio(mpeg: PSMPEG; stream: PUInt8; len: Integer): Integer;
+cdecl; external {$IFDEF __GPC__}name 'SMPEG_playAudio'{$ELSE} SmpegLibName{$ENDIF __GPC__};
+
+{ Wrapper for SMPEG_playAudio() that can be passed to SDL and SDL_mixer }
+procedure SMPEG_playAudioSDL(mpeg: Pointer; stream: PUInt8; len: Integer);
+cdecl; external {$IFDEF __GPC__}name 'SMPEG_playAudioSDL'{$ELSE} SmpegLibName{$ENDIF __GPC__};
+
+{ Get the best SDL audio spec for the audio stream }
+function SMPEG_wantedSpec(mpeg: PSMPEG; wanted: PSDL_AudioSpec): Integer;
+cdecl; external {$IFDEF __GPC__}name 'SMPEG_wantedSpec'{$ELSE} SmpegLibName{$ENDIF __GPC__};
+
+{ Inform SMPEG of the actual SDL audio spec used for sound playback }
+procedure SMPEG_actualSpec(mpeg: PSMPEG; spec: PSDL_AudioSpec);
+cdecl; external {$IFDEF __GPC__}name 'SMPEG_actualSpec'{$ELSE} SmpegLibName{$ENDIF __GPC__};
+
+{ This macro can be used to fill a version structure with the compile-time
+ version of the SDL library. }
+procedure SMPEG_GETVERSION( var X : TSMPEG_version );
+
+implementation
+
+{$IFDEF __GPC__}
+ {$L 'smpeg'} { link smpeg.dll.a or libsmpeg.so or libsmpeg.a }
+{$ENDIF}
+
+procedure SMPEG_double(mpeg : PSMPEG; doubleit : Boolean );
+begin
+ if doubleit then
+ SMPEG_scale( mpeg, 2 )
+ else
+ SMPEG_scale( mpeg, 1 );
+end;
+
+procedure SMPEG_GETVERSION( var X : TSMPEG_version );
+begin
+ X.major := SMPEG_MAJOR_VERSION;
+ X.minor := SMPEG_MINOR_VERSION;
+ X.patch := SMPEG_PATCHLEVEL;
+end;
+
+end.