diff options
| author | marco <marco@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2008-01-27 10:35:18 +0000 |
|---|---|---|
| committer | marco <marco@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2008-01-27 10:35:18 +0000 |
| commit | c1de70bf2792e10edd0992380dc3a0243c52c7c9 (patch) | |
| tree | c4a3c0c1dc6afee35a5dd536c0c00371401ed049 /packages/sdl | |
| parent | bb8ca14d09ca9536577ebe2ed1d09a62261d4d4c (diff) | |
| download | fpc-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/LGPL | 504 | ||||
| -rw-r--r-- | packages/sdl/LGPL.addon | 25 | ||||
| -rw-r--r-- | packages/sdl/MPL-1.1 | 470 | ||||
| -rw-r--r-- | packages/sdl/Makefile | 2444 | ||||
| -rw-r--r-- | packages/sdl/Makefile.fpc | 33 | ||||
| -rw-r--r-- | packages/sdl/README | 7 | ||||
| -rw-r--r-- | packages/sdl/fpmake.pp | 91 | ||||
| -rw-r--r-- | packages/sdl/src/jedi-sdl.inc | 438 | ||||
| -rw-r--r-- | packages/sdl/src/libxmlparser.pas | 2688 | ||||
| -rw-r--r-- | packages/sdl/src/logger.pas | 189 | ||||
| -rw-r--r-- | packages/sdl/src/powersdl.inc | 176 | ||||
| -rw-r--r-- | packages/sdl/src/sdl.pas | 4288 | ||||
| -rw-r--r-- | packages/sdl/src/sdl_gfx.pas | 691 | ||||
| -rw-r--r-- | packages/sdl/src/sdl_image.pas | 345 | ||||
| -rw-r--r-- | packages/sdl/src/sdl_mixer.pas | 1122 | ||||
| -rw-r--r-- | packages/sdl/src/sdl_mixer_nosmpeg.pas | 967 | ||||
| -rw-r--r-- | packages/sdl/src/sdl_net.pas | 629 | ||||
| -rw-r--r-- | packages/sdl/src/sdl_ttf.pas | 501 | ||||
| -rw-r--r-- | packages/sdl/src/sdlutils.pas | 4363 | ||||
| -rw-r--r-- | packages/sdl/src/smpeg.pas | 435 |
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;ü" + 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. |
